Webpack less-loader Missing Base Path on Production Build - javascript

I've got a vue-js app that uses webpack. Everything works fine in development and test environments, but I'm having trouble getting it to build for production.
I've got background images in the LESS files. The image files are in /static. (I'm not sure whether that's kosher or if they should be in side src/assets.)
At any rate, when the LESS has something like this:
background-url: url("/static/img/foobar/my-image.svg")
Then the compilted CSS will have the same url
background-url: url("/static/img/foobar/my-image.svg")
When the browser loaders, it can't find that imgate file. The browser is attempting to find the file here:
file:///static/img/foobar/my-image.svg
Can anyone recommend a way to prepend the absolute path when the app builds for production?

Do you have your static assets outside of our project directory in /static ?
Otherwise I don't get why your browser is trying to request it from file:///static/img/foobar/my-image.svg
anyway, your static assets should be part of your repo/project. They do not need to be in src directory, a /static folder within the root of your project is just fine.
when you compile your application - let's say into a dist folder - you should copy the images also in that dist folder. In my app I use the copy-webpack-plugin for that task (I have my images in ./public/assets/img/.. and I reference them as /assets/img/..)
const CopyWebpackPlugin = require('copy-webpack-plugin');
...
plugins: [
...
/** copy all files from the public folder to the compilation root */
new CopyWebpackPlugin([{
from: 'public',
to : ''
}]),
...
also you should make sure that you have the file-loader in place for your static assets. I use it like so:
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)(\??\#?v=[.0-9]+)?$/,
use : 'file-loader?name=assets/[name].[hash].[ext]'
}
I hope this will help you to resolve your problem.

I ended up moving the images into assets/img and then updating my webpack config to specify the directory using publicPath. Here's what it ended up looking like:
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'file-loader',
include: [resolve('src')],
options: {
limit: 10000,
name: '/[name].[hash:7].[ext]',
publicPath: path.resolve(__dirname, 'app')
}

Related

Webpack - Change 'src' path of javascript files in index.html

I am facing an issue after building my strapi application (using webpack).
After i executed yarn build, my index.html imports javascript files using the <script> tag.
The issue comes here, in my build folder, there are all of my files (images, js files etc...), and 0 subfolder.
But inside my index.html, it imports from an invalid path:
<script src="admin/file.js"></script>
I want to change this src with Webpack to look like that :
<script src="./file.js"></script>
Anybody got a solution ?
Thank you.
Finally, i found the fix.
I am using Strapi for this web app.
Strapi automatically fills webpack with publicPath "/admin/".
However, webpack doesn't understand and put every files (js, img, html) in the same directory, at the same level (no subfolders).
So inside src/admin/, remove the word "example" from the file name "webpack.config.example.js"
Open this file and insert this code
'use strict';
module.exports = (config, _webpack) => {
config = {
...config,
output: { ...config.output, publicPath: './'}
}
return config;
};

How to make webpack-dev-server serve my index.html

I'm trying to get an extremely simple bare-bones TypeScript project setup with Webpack and I'm having an incredibly hard time for some reason.
I followed this guide and everything is working. When I simply run webpack my files will bundle and compile and be outputted into the dist directory. From there I can host them on a local server and it all works fine.
However, I want to avoid having to manually bundle and compile my code every single time I make a change, and I'd like for this to be done automatically each time I save my files. As far as I can tell this is a common use for Webpack and so I'm not sure why I'm having such an incredibly hard time finding any good information on it.
I decided to use the webpack dev server to accomplish this, so I read this tutorial and for the life of me I can't find anybody who explains how to get it to also server my index.html? When I run webpack serve --mode=development all goes well, and when I navigate to the localhost port that I server to I get a 404 error.
One of the "tips" on the previously linked page reads
If you're having trouble, navigating to the /webpack-dev-server route will show where files are served. For example, http://localhost:9000/webpack-dev-server.
When I navigate to localhost:1234/webpack-dev-server it tells me that it's only serving a single file: bundle.js Clearly a JavaScript file alone is not going to work, and I need it to also serve the index.html file that's in my dist directory.
Now, my knowledge here is very limited as this is my first time working with Webpack, but here's all the detail I can give and hopefully it's not accidentally totally unrelated:
Whenever my dev server reloads itself (whenever it's booted up or if a watched file changes while it's running) it only updates the bundle.js file that it's serving. It doesn't update the bundle.js file stored in my dist directory on my hard drive. How can I make it update both?
And also, how do I make the server also serve my index.html file instead of only the bundle.js? Where is it even getting that bundle.js from? Is it compiling all of my code from scratch to create that js file or is it taking that out of the dist directory?
And additionally, am I going about this totally in the wrong way? Where should my index.html even go? I put my TypeScript files into a src directory and they're converted to .js files and moved into my dist directory... Should I also put my index.html inside src or does it belong in dist or somewhere else entirely? When I put index.html in src it doesn't get copied over into dist, it just ignores it completely. If my index.html file doesn't belong in src it must belong in dist, but if it belongs in dist then how can I expect the dev server to find it and serve it along with the other TypeScript files in src? Why can't the dev server just serve everything in dist and automatically compile everything from src into dist? I must be misunderstanding the flow of it all, but I have no idea where to look for an explanation and I've been at this for several hours now.
Just a general explanation of how it all works would be very helpful as well, as I can't find a single article or forum post anywhere that details all the spaghetti going on with Webpack. I've been avoiding bundlers and all this NPM mess for as long as I can because I constantly run into issues like this, but I finally decided to jump in and just push through all the mess and I'm already regretting it. If someone could just point me (and other people having similar problems) to some good resources for learning about all the automagic going on that would be hugely appreciated. The Webpack documentation and guides are very much worthless to a newbie.
My Webpack config file:
const path = require("path");
module.exports = {
entry: "./src/index.ts",
module: {
rules: [
{
test: /\.tsx?$/,
use: "ts-loader",
exclude: /node_modules/,
}
]
},
resolve: {
extensions: [".tsx", ".ts", ".js"]
},
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist")
},
devServer: {
compress: false,
static: false,
client: {
logging: "warn",
overlay: {
errors: true,
warnings: false
},
progress: true
},
port: 1234, host: "0.0.0.0"
}
};
Is your entry set in webpack? So that it is included?
entry: {
main: 'path/to/index.ts'
},
You could also try adding to your index.ts file
require('file-loader?name=[name].[ext]!../index.html');
Or
require("./src/index.html");
// Then In your webpack config file add a loader
loaders : { { test: /\.html/, loader: 'file?name=[name].[ext]' } }
Otherwise you could always copy this file over with webpack copy plugin
{
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html'
})
]
}
will need to run npm install --save-dev html-webpack-plugin to install it. As well as move your index.html file into your src folder
Please visit localhost:1234/bundle (Where bundle.js is your bundled file) the magichHTML route, which will load the HTML file with the bundled script.

Webpack: output.path, publicPath and chunkFilename selecting concept for projects where html and js files are not in the same folder

From the webpack documentation for output.publicPath:
Simple rule: The URL of your output.path from the view of the HTML
page.
module.exports = {
output: {
path: path.resolve(__dirname, 'public/assets'),
publicPath: 'https://cdn.example.com/assets/'
}
};
Above rule is actual for single-page applications, where usually index.html and index.js are in the same folder. However, in the projects of multi page websites, usually special folder like js or scripts is being created. So the file structure of output folder of project could be like:
I tried a lot of combinations of output.path output.publicPath and output.chunkFilename, however still do not understand, how to correctly select the combination of above parameters to make dynamic load works (e. g. const MODULE = import('./loadOnDemand/testModule') which is chunks/chunk__0.js in output folder). Please tell me the concept, how to select output.path publicPath and chunkFilename, which will works for above file system, and also could be scaled on below file system:
Have you tried webpack magic comments to automatically target the chunk names?
https://medium.com/faceyspacey/how-to-use-webpacks-new-magic-comment-feature-with-react-universal-component-ssr-a38fd3e296a
const MODULE = import(/* webpackChunkName: 'test' */'./loadOnDemand/testModule')

Make webpack move files from src to dest without processing it

I have some sites running with JSF and some vanilla ES6 that is being processed with webpack (Running 4.6).
The problem is that webpack adds something to my jsf.js file when it moves the file to my dest folder, and doesn't work with how JSF needs to be run.
Setup: There is the jsf.js and the vanilla ES6 files in a src folder. I then use webpack to process and move the bundle and the jsf.js file to a dest folder.
The JSF.js file is already minimized in the src folder and cannot be uglified so I have added exclude on uglify:
optimization: {
minimizer: [
new UglifyJsPlugin({
exclude: /(jsf.js)/,
})
]
}
The jsf.js also has its own entry btw.
So my question is, how do I make webpack only move the jsf.js and add nothing to it? There must be some kind of exclude that I am missing here. I use no plugins other than uglify.
If you just want copy jsf.js to dist directory. you should try copy-webpack-plugin, not give it its own entry.
install it throught npm:
npm i -D copy-webpack-plugin
require it in webpack.config.js
const CopyWebpackPlugin = require('copy-webpack-plugin')
add to plugins's array
[
new CopyWebpackPlugin([
{ from: 'path/to/jsf.js', to: 'dist/' }
])
]

publicPath with react hot loader

I'm not quite sure what the publicPath in webpack does. Specifically, output.publicPath. In the github docs, I see this
https://github.com/webpack/docs/wiki/configuration#outputpublicpath
The output.path from the view of the Javascript / HTML page.
For reactjs hot loading, I have
output: {
path: path.resolve('./public/bundle/'),
// path: './public/bundle',
filename: 'main.js',
// Webpack dev server is bound to port 8080, we have to force use of absolute URL, using the publicPath property
publicPath: 'http://localhost:8080/public/bundle/'
},
Does this mean that the built webpack files (main.js) is placed in my dev-server http://localhost:8080/public/bundle/ ?
Yep, Webpack needs to know where you'll host the generated bundle file (or any other assets it generates) so that it can request additional chunks or files that are loaded from file-loader or url-loader. Hence in this case, when you start your webpack-dev-server, you'll be able to access your bundle file at: http://localhost:8080/public/bundle/main.js (any related assets like images, commonchunk, fonts, etc will be under that path)
Outside of dev-server, you can use it to define the location of your assets (from a custom directory or even a CDN)

Categories