Image not found when using the stenciljs bundle - stencils

I have this stenciljs component which uses an svg images like this:
...
return (
<button>
<img src="../../assets/icon.svg"/>
<slot/>
</button>
);
...
My folder structure is
src/
assets/
icon.svg
components/
button/
button.tsx
Now, when I do stencil build it creates the dist folder with everything in it.
I copy the dist folder into my site, which has the following structure:
my-web/
index.html
bundle/
<content from dist>
And inside the index.html I load the bundle
<script src="/bundle/my-componets.js"></script>
This works as expected but the asset is loaded from /assets/icon.svg which does not exist (404). Any suggestions what I need to do to fix this?

There are two ways to do this I guess.
First:
Take a look at https://stenciljs.com/docs/config#copy.
Using this config setting you can copy your assets (.svg files & whatever) to your dist folder. You can also specify a destination for the files to be copied to, like:
copy: [
{ src: "../path/to/the/files", dest: "./path/to/paste/the/files" }
],
Second:
Import the asset to the JS of your component. You'll need a Rollup Plugin to handle the import (example: rollup-plugin-svg-to-jsx - but there are others). After setting this plugin up, you can just do:
import * as Icon from "path/to/your/svg"
...
return (
<button>
<Icon />
<slot />
</button>
);
The first one will keep your JS bundle a little smaller and load the Icon.svg file when you place the button somewhere on the page.
The second one will bundle the svg into your JS and load together with your JS - so there is no Button without the Icon at any times.

From what you intend to do, I understand your goal is to have fully runnable standalone application inside ./dist after build.All sourcefiles which are needed to run the application should be placed there.
This means you will need to create a copy of the sourcefiles (staticfiles) into the distribution folder in the way my-web/assets/icon.svg in order for the application to locate and access it.

Related

Pass assets image path as dynamic inline style background-image url (Nuxt.js)

I'm working on a Nuxt.js app and I want to set the background image of an element dynamically with images from the assets folder, this is what I did:
<template>
<div>
<div
v-for="(image, imageID) in images"
:key="imageID"
:style="bgImg(image)"
/>
</div>
</template>
<script>
export default {
data() {
return {
images: [
'~assets/img/image1.jpg',
'~assets/img/image2.jpg',
'~assets/img/image3.jpg',
'~assets/img/image4.jpg'
]
}
},
methods: {
bgImg(img) {
return `background-image: url(${img})`
}
}
}
</script>
Expected behavior
The div is rendered with dynamic background images
Actual behavior
The background image is not rendered. If I put the static assets path into css file, it is rendered
How do I have to pass the path for this to be rendered correctly?
Nuxt Webpack build process messes with some urls
So the issue is that paths in templates and CSS are processed by Webpack's file-loader when the project is built. For example ~assets/ gets rewritten at build time to be the actual path after webpack's processing is done.
However, since you're specifying the path strings as part of the vue.js data, Webpack doesn't touch them.
To resolve this create a "static" directory at the root of your project (assuming you don't have one already). Inside of that, create an "images" directory. Webpack will copy everything thing inside static to the dist folder when the build is run.
The path to these images to use inside your component is then /images/filename.ext

how to use the image in the <img> on Angular 5

I have a local image in my folder. but I can't use this image. Folders structure:
I want to use logo.jpg in login.component.html. I am using this code:
<img src="img/logo.jpg">
But isn't work for me
TL;DR: Supposing you are using #angular/cli try to move your img folder under src\assets and then do <img src="assets/img/logo.jpg">.
Standard way is to put assets to assets folder under your app source root. The builder is told in angular.json to include assets by defining (for example):
projects.<your-project>.architect.build.options.assets: [
"src/assets",
"src/favicon.ico",
"src/manifest.json"
]
Whatever is defined there will be copied verbatim to your dist folder.
Note that assets must be under src root, somewhere. Therefore trying to add "src/../img" to config will fail. At least with my config and CLI.
Edit: Just noticed you mention Angular5. That is long time ago but IIRC the config file there was named .angular.json (see the dot). The structure of config is slightly different, just look for "assets".
you need to provider the entire relative path
i think it's:
src="../.././img/logo.jpg"
or maybe
src="../../../img/logo.jpg"
change the path to: '../../../img/logo.png'
or Move the imgs to under assets in src, src/assets
and then refer in your img src as:
img src="assets/img/logo.png">

Minimizing Individual Assets with Webpack

I would like to optimize a wordpress website with webpack. The application is not a single page app, and each page requires their own styles, scripts, and images in the head. I would like to use webpack to minimize css, js, and images in place. I don't need a single bundle file.
In a folder with three css files, I would like to iterate through each of the files and minimize them.
css/
page.css ---> page.css(minimized)
header.css ---> header.css(minimized)
footer.css ---> footer.css(minimized)
I would like to do the same with js files and use an image optimizer for jpgs, png, ect. Can this be done with webpack? If so, how could this be done? I have read about multiple entry points but that does not seem to be what I need. Thanks!
No, multiple entry points will still only give one output. What you could do, is write a wrapping script which wraps your webpack.config.js and having the entry config variable set to be dynamic.
Pseudo-code:
import glob from 'glob'
import webpack from 'webpack'
import config from './webpack.config'
const files = glob.glob('**/my-entry-file.js');
files.forEach((file) => {
config.entry = file;
webpack(config);
});

How to handle CSS with meteor?

I am building a test app to learn how to organize multiple files with METEOR.
I have a head.html and inside I have the following link to my custom CSS:
<!-- Custom CSS -->
<link type="text/css" rel="stylesheet" href="/stylesheets/globals/style.css"/>
Very normal, Yet I have trouble to make that working.
Here is my app directory:
-app folder
---client
-----head.html
-----index.html
-----stylesheets
-------globals
---------style.css
I know it seems to be a very basic question but I can not figure it out.
Basically you have 2 ways of inserting CSS in a Meteor project :
Using the Meteor build tool to automatically concatenate and minify all your CSS files living in the client/ directory : in this case you don't need to import your stylesheets using a link tag in the head. This is perfect for vital CSS files that your app should load when started.
Example : put your CSS file under client/stylesheets/globals/style.css and that's it, no need to import it, it's automatically injected in your project by Meteor.
Using the classic way of importing stylesheets in a web application : you can put your CSS files inside the public/ directory and they will be served by your app server. In this case the Meteor build process will be skipped so files won't be concatenated together nor minified. Use this method when you want to lazy load big CSS files only needed in a subpart of your app (for example admin section styling).
Example : put your minified CSS file under public/stylesheets/admin/style.css, and use something like iron:router to load the CSS file when hitting the admin route.
Router.route("/admin", {
// onRun hooks executed only once
onRun: function(){
// create a link taf holding a reference to our publicly served CSS file
var link=$("<link>",{
rel: "stylesheet",
href: "/stylesheets/admin/style.css"
});
// append to the head tag
$("head").append(link);
}
});

Integrate CKEditor in Meteor

I'm trying to use CKEditor in a meteor application:
My attemps:
Put CKEditor folder with all the files (js, css, lang, plugins and skins) in the public folder, include the reference to the javascript file (ckeditor.js) in the header and use the appropiate class in textarea elements. Failed because the editor only works if the textarea is in the body (in any template the textarea control remains unmodified).
Put the javascript files (ckeditor.js, config.js, styles.js) in client/lib/compatibility folder and the remaining files in the public folder. This time the application cant locate the files (skins, plugins, ...) because is looking for localhost:3000/client/lib/compatibility/ckeditor/ ...
Has anybody make this integration works before?
I got this working and wanted to post a solution for future visitors. First, you need to put everything from the CKEDITOR build download in the public folder. CKEDITOR comes with all sorts of stuff and references everything based on relative directories.
Your public folder should have a directory named ckeditor it should contain contain the following files and folders:
adapters
lang
plugins
skins
ckeditor.js
config.js
contents.css
styles.js
In your primary layout file reference CKEDITOR like so:
<head>
<script type="text/javascript" src="/ckeditor/ckeditor.js"></script>
<script type="text/javascript" src="/ckeditor/adapters/jquery.js"></script>
</head>
In your template:
<template name="yourTemplate">
<textarea id="content" name="content"></textarea>
</template>
Finally, in the rendered function of your template:
Template.yourTemplate.rendered = function() {
$('#content').ckeditor();
};
Normally, you would say this.$('#content').ckeditor() but that doesn't work because CKEDITOR is in your public folder. As a result, you need to the global reference to the #content element.
Put only the CKEditor files that you would've included in <head> inside a folder in client/lib, i.e. client/lib/ckeditor. That's all you need to do to get them served to the client: there's no need to reference anything in any <head> or anything like that. All .js and .css files that Meteor finds inside client are automatically concatenated and served to the client. This applies to any client-side library, not just CKEditor.
The next thing you need to do is cause CKEditor to be initialized on the pages that use it. Say you have a template called edit with a textarea with an ID of editor. And say you're also loading the CKEditor jQuery Adapter. Inside a JavaScript file within client, put:
Template.edit.rendered = function() {
$('#editor').ckeditor();
}
The key here is that the initialization happens after the textarea editor exists and is ready, because this code is executed after the edit template is fully rendered. It will be reexecuted anytime edit is rerendered. Any other client-side library is included and initialized similarly.
EDIT Image files referenced via .css are a pain in Meteor. The "proper" way to deal with them is to put them all under the folder public, in this case for example public/ckeditor. Then edit the CKEditor .css files so that all references to image URLs point to your new folder at the root, i.e. /ckeditor/image1.png etc. (leave out "public").

Resources