What files do webpack loaders work through? - npm

When you set the regex after the test key in a loader object, does that look through all files in your project and load them using the loader you've designated, even if those files weren't required by the file in your entry point? Does this then get placed in the bundle.js file?

No it will only include what is required by your script.

<img src={ require('../some/img.png') } /> is a way to tell Webpack that your source code needs this image to run.
In a production Webpack build, this will get compiled into something like <img src="http://yoursite/whatever/89de0f2.png" />. The require() statement is never executed, it's replaced with valid Javascript code. This replaced code is what's put in bundle.js.
The image is then put into whatever output folder you specify (like a local dist/ folder), and it's renamed to something unique, which is usually some hash of the file contents, resulting in 89de0f2.png. (I made up this name for the example, but it usually looks something like that).
Now when you upload that file, 89de0f2.png, your source code will reference 89de0f2.png exactly, so that version of the image is guaranteed to exist. This is how Webpack gives you production guaranteed asset loading.
Wepback will only put img.png in your dist/ folder as 89de0f2.png if you specifically require it. Any other images will not be put in that folder.
You may also be asking about base64 encoding images and putting them directly into your bundle.js file. In this case, no image is put into dist/, but all the other rules reply. The require() call is still replaced with valid Javascript.
There is one case where Webpack will require multiple assets. You can require patterns, like <img src={ require.context( './images', true, /\.png/ ) } /> and Webpack will build all png files in that directory into the dist/ folder. See this Stackoverflow question for more context.

Related

Vue: Cannot find module (image) in the file

I wrote a line which shows a picture like
And my asset folder is structured as
Yet this is throwing
Solutions I've tried:
Tried using
.
Still the same problem.
Any solutions?
Your screenshot shows assets under public, but your import URL uses the # prefix, which is a common alias for <projectRoot>/src.
You can move public/assets to src/assets so that the #/assets URL would be found:
public/assets --move--> src/assets
This solution has the advantage of minimizing the build output, only including files that are actually used in code. The included images also go through Webpack's processing, e.g., if you've configured image optimization.
Alternatively, you can keep public/assets and use a static asset URL, which is the base URL prefixed to the path under public. For the play.img and a base URL of / (the default), the static URL would be /assets/img/play.img:
<img src="/assets/img/play.img">

Images uploaded in Vue.js production mode not showing

I am a bit new to Vue.js. I am doing a social media application that allows users to upload and share images with others. I store my images in src/assets folder during development. However, when I build the project, all images are put in the dist folder. Therefore, what can I do to enable users to still upload images on production? Do I create the assets directory in the dist folder?
I have since tried different ways, including storing images on the backend. In dooing this, I reference the backend path relatively, using, for example, ../../../backend/public/assets..., and it works on development. However, when I build, the images that existed in the backend directory at the time of building are visible, however, whenever I try uploading more on production to the ../../../backend/public/assets... directory, they are uploaded successfully but are not visible (that is on production). I get an error that Cannot find module './image_name.image_extension'.
What am I doing wrong?
I have seen similar questions like this but there was no answer.
You must set your public path and change your way!!
first step to do is creating vue.config.js in your root directory, if you want to know more details, read this: https://cli.vuejs.org/config/
for example, I define prefix path for my files:
module.exports = {
publicPath:
process.env.NODE_ENV === "production" ? "/" : "/",
};
remember, It's better if you use "#" to define your paths.
for example, if you want to load a image which located in src/assets/files/img/myImage.png, you can use #/assets/files/img/myImage.png in template section for binding or script section of your .vue files!
It always help you to find correct path of your files.
and finally your way is not standard because "src/assets/..." will used for compiled scripts and styles and also your files which you want to use on your UI layout like static images. so you have to use "public/assets/..." directory to save your file, then you will see everything is going well for you.
if you have a more question or stuck solving this problem again, I'm here to fix your issues.

vue access to images

I'm trying to view an image in one of my pages. I'm on a latest node-express-vue-nuxt-babel setup. My final goal was:
<img :src="'#/assets/images/projects/' + project.image" width="50px" />
I started with the above, but I got a 404. So I tried with a specific image:
<img src="#/assets/images/projects/5a2db62e346c1.jpg" width="50px" />
and it worked, but going back to dynamic source didn't and:
to <img :src="'#/assets/images/projects/5a2db62e346c1.jpg'" width="50px" />
was enough to produce the 404 again. The 404 was in the console, the page was loading fine with no errors but alas no signs of the image(s). Inspecting the elements made me notice that the dynamic :src became:
<img src="#/assets/images/projects/5a2db62e346c1.jpg" width="50px" />
and the 'static' src became:
<img src="/_nuxt/assets/images/projects/5a2db62e346c1.jpg" width="50px" />
So to make it work I had to renounce to the initial "#" and substitute it with "_nuxt":
<img :src="'_nuxt/assets/images/projects/' + project.image" width="50px" />
Ok, nice, but.. why?
Do this: <img :src="require('#/assets/images/projects/' + project.image)"/>
VueJs
There are several asset URL transforms rules in vuejs. Here is one of them:
If the URL starts with #, it's also interpreted as a module request. This is useful if your webpack config has an alias for #, which by default points to /src in any project created by vue-cli
For more information : Asset URL
You are using webpack for bundling the application.
At a very high level webpack looks for require and takes care of bundling your scripts. Exactly what that means depends on your specific configuration, but it usually gathers all the js files in one file, usually minifies and removes unused code.
Webpack is not limited to js files. By the use of plugins it can handle extracting images from html files, load resources from urls and much more.
The way it ends up loading images is still by the use of require, the plugins just plug everything in so webpack can handle them. That being said, require is a compile time feature and if the path can't be determined at compile time webpack will not work. Webpack will usually translate the image path to a path that's available at runtime (usually they are different and depend on your webpack config).
When you bind src like this:
:src="'#/assets/images/projects/' + project.image"
The path can't be determined at compile time and as such vue will resolve it at run time, but webpack already finished and it will not translate your path.
There are a couple of ways to handle this:
As you found out: using a static runtime path, that is not handled by webpack, will work. The downfall is that if you change the way you build your project you'll need to update all references (in your case _nuxt). Note: if using vue.cli, you usually get a folder called static that is used exactly for this.
Use a binding, but bind to the run time path. This has the same downside as above and also the following: webpack has cache-busting technics that mangle file names, so knowing the final name of an asset that is handled this way by webpack is virtually impossible.
It worked also with backticks:
<img :src="require(`#/assets/images/projects/` + project.image)" width="100px" />
Thanks guys!

In VueJS is there a way to read environmental variables or config values into a static/ file during build step

Background:
Using VueJS, specifically in regards to PWA template https://github.com/vuejs-templates/pwa
There is a build step npm run build which bundles the project and transpiles any Vue into a distribution browser JS.
The files in /static/ are "static" and just copied into dist, but I am wondering if it's possible to template it at all, or read in some dynamic values.
Question:
Is it possible to have static files that servce under /static in the url, but also during build can accept dynamic values?
More context:
The problem is Vue compiles everything into the dist directory.
All non-static assets are cached and get a unique url each build, whereas static files (I know this is configurable, but you arguably want your non-static assets to have caching) have absolute paths.
Server Routing to map a file in /static/ to a cached dynamic file is outside of Vue. The question pertains to needing to host some "absolute pathed files" (static), but some files might have internally 1-2 urls that need to change in the files depending on what config is used, dev, prod, staging.. just as an example of the use case.
The solution I found was to use CopyWebpackPlugin which comes natively inside build/webpack.prod.conf.js
This is the plugin that copies files from static into dist/static.
You can use the process.env.NODE_ENV to allow you to copy specific files from static into dist.
I decided just to keep environment specific copies of the files with values changed, but you could easily add code to that file to parse and copy over whatever specific files you want.
I think most people put dynamic configuration values in a file under public/ then use javascript fetch to load those values in Vue components. Webpack will copy the files in public/ to the web root (dist/) and it will avoid compiling those config values into the minified javascript. If you put files in static/ and use import or require to load them into Vue components then webpack will resolve those during build time and compiling them into the minified Javascript - which is probably not what you want.

using npm scripts to Inject *.js and *.css into index.html

I´m looking into switch from gulp/grunt to only use npm scripts.
But I cant really solve how to get *.js and *.css from a given path and add it to the index.html file.
must I add it thru a "index.js" file or can I do something like...
"scripts": {
"inject": "inject src/app/*.js",
},
and then it will add it in my index.html where I have specified it like...
/* inject:js */
The suggestion by Chris Traveis worked out pretty nice.
So the answer to my problem was solved using https://www.npmjs.com/package/postbuild
There were no answers in the last 3 months on this popular topic, probably because there are wrong assumptions in the question. Distilling your question,
...how to get *.js and *.css from a given path and add it to the index.html file
To be short, do it manually. Use a good npm boilerplate such as npm-build-boilerplate and add the compiled JS and CSS files manually into your HTML.
... must I add it thru a "index.js" file, or <2nd option>
No. Add the files manually. Let me elaborate more.
With npm scripts you construct a pipeline and you know where your uglified JS files and compiled SCSS files are rendered. Yes, I have "main": "index.js", row in my package.json, but there's no "index.js" in my project at all. I get npm scripts to crunch files in various folders, to output them into other folders and I manually add end CSS and JS files into HTML templates (in my case, static Hugo website's templates).
I see one case where "dynamism" in the HTML is needed — when you want to bust cache and add the unique strings to the end-point CSS/JS file names. However, then you might want to consider scripts that count MD5 hash of the files' contents, because if you run the build multiple times and your existing CSS or JS files haven't changed, you want to keep the old file names. Visitors might have cached them (and think about CDN too). In this sense, npm postbuild script mentioned in the comments above is inferior because it just uses "version" counter. Look for alternatives to npm postbuild to bust caches.