Webpack add query string to bundle for cache-busting - caching

so in my index.html, I have this line to include the webpack bundle
<script src="/dist/bundle.js"></script>
And my webpack config looks like this:
const path = require("path");
const webpack = require("webpack");
module.exports = {
entry: "./src/main.js",
mode: "development",
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
loader: "babel-loader",
options: { presets: ["#babel/env"] }
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
]
},
resolve: { extensions: ["*", ".js", ".jsx"] },
output: {
path: path.resolve(__dirname, "dist/"),
publicPath: "/dist/",
filename: "bundle.js"
},
devServer: {
contentBase: path.join(__dirname, "public/"),
port: 3000,
publicPath: "http://localhost:3000/dist/",
hotOnly: true
},
plugins: [new webpack.HotModuleReplacementPlugin()]
};
How could I modify this, to add a query string (?v=some_nr) to the bundle when I run webpack --mode production. I can copy the index.html to dist/index.html or some other location, if needed, I'll be moving it to the webroot automatically anyway afterwards.

Related

Loading local images with webpack

Hi I am trying to load local images with webpack, it compiles successfully however I get the following error (and no image)
GET http://192.168.1.196:3000/b09d0fa90cacadcad6ce1679aea3d2ee.png 404 (Not Found)
Here is my webpack.config.js file:
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'public/scripts'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['env']
}
}
},
{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' }
]
},
devServer: {
contentBase: path.resolve(__dirname, 'public'),
publicPath: '/scripts/'
},
devtool: 'source-map'
}
Here is how I am importing the image
import goku from '../public/images/goku.png'
I am trying also with require in the img directly with the same result.
<img src =${require('../public/images/goku.png')}>
<img src =${goku}>
Your problem is actually that you missed a publicPath on output:
output: {
path: path.resolve(__dirname, 'public/scripts'),
filename: 'bundle.js',
publicPath: '/scripts/'
},
devServer: {
contentBase: path.resolve(__dirname, 'public'),
publicPath: '/scripts/'
},
The property publicPath on output has to match the publicPath on devServer.

Webpack generates wrong url for images that were included using file-loader

I am using webpack file-loader to include images in my build. Webpack compiles fine and copies images from dev/assets to dist/images
BUT the tag in the generated HTML is wrong:
<img src="/dist/images/triangle.svg">
It should be:
<img src="./images/triangle.svg">
Is my webpack config wrong for file-loader?
.vue file:
<div>
<img src='./images/thing.png'>
</div>
.style {
background: url('./images/anotherthing.png');
}
Webpack config (simplified)
module.exports = {
entry: './src/index.ts',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
module: {
rules: [
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/'
}
}
]
}
webpack config (complete)
var path = require('path')
var webpack = require('webpack')
module.exports = {
entry: './src/index.ts',
output: {
path: path.resolve(__dirname, './dist/'),
publicPath: './',
filename: 'js/build.js'
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
'scss': 'vue-style-loader!css-loader!sass-loader',
'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax',
}
}
},
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: {
appendTsSuffixTo: [/\.vue$/],
}
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath:'./images/'
}
},
{
test: /\.(json)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: './data/'
}
}
]
},
resolve: {
extensions: ['.ts', '.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
devServer: {
contentBase: './dist',
historyApiFallback: true,
noInfo: true
},
performance: {
hints: false
},
devtool: '#eval-source-map'
}
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map'
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
}
You probably just want to set publicPath: '/'.
Think of publicPath as the directory of your assets relative to the root of the public facing domain. If your server is serving files from /dist to example.com, that would mean that assets in /dist/images are publicly accessible at example.com/images (file-loader already adds the /images bit as you've witnessed).

html loader set wrong path or ignore image from index.html

I have problem in my webpack, when i set attrs: [':data-src'] in my html-loader i have good path in index.html like this: <img src="img/logo.png" width="180" height="96">, but when I use npm run build I haven't images from this index in dist folder. When I have default attrs=img:src i have images, but my path looks like: <img src="../img/../img/logo.png" width="180" height="96">. I tried use attrs: ['data:src', 'img:src'], but it doesn't work.
My config:
var webpack = require('webpack');
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
context: path.join(__dirname, "src"),
entry: "./js/index.js",
output: {
path: __dirname + "/dist/js",
filename: "bundle.min.js"
},
module: {
loaders: [{
test: /\.js?$/,
exclude: /(node_modules)/,
loader: 'babel-loader',
query: {
presets: ['es2015'],
}
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(html)$/,
use: [{
loader: 'html-loader',
options: {
attrs: ['data:src', 'img:src']
}
}]
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: '../img/',
publicPath: '../img/'
}
}]
},
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin({
mangle: false,
sourcemap: false
}),
new HtmlWebpackPlugin({
filename: '../index.html',
template: './index.html'
}),
],
};

Browser debugger not working with Webpack 2 and webpack-dev-server

I've spent last few hours to set up a new project utilizing Webpack 2 and Babel 6.
The problem I have is non working debugger (any browser). Breakpoints are simply ignored. Using debugger; works fine but browser does not breaks execution exactly in that line.
webpack.config.js:
const path = require("path");
module.exports = {
entry: path.resolve(__dirname, "src", "index.js"),
output: {
filename: "app.js",
path: path.resolve(__dirname, "dist")
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
}]
},
devServer: {
contentBase: path.resolve(__dirname, "dist")
}
};
.babel.rc:
{
"presets": [
"latest"
]
}
I'm running the whole thing with webpack-dev-server -d
devtool: "source-map", option in webpack config should solve your problem.
entry: ['babel-polyfill', './src/index.jsx'],
output: {
filename: 'js/bundle.[hash].js',
path: path.resolve(__dirname, 'build'),
publicPath: '/'
},
resolve: {
extensions: ['.js', '.jsx'],
alias: {
config: path.join(__dirname, `config/${env}.configuration.js`)
}
},
**devtool: "source-map",**
module: {
rules: [
{
test: require.resolve('jquery'),
use: [
{
loader: 'expose-loader',
options: 'jQuery'
}
]
},

Webpack, "hot-reload" or "live-reload" sass?

Is there a way to get webpack to "recompile" sass and reload your page on the fly?
I've been searching around but have not found an example.
Here is what I've got:
My folder structure
-app
---public
------dist
---------index.html
---------sass
------------webpack.scss
It seems like my sass only recompiles when I run webpack but it doesn't recompile when I am running the webpack-dev-server
var path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var webpack = require('webpack');
module.exports = {
entry: {
app: './app/main.js',
//All 3rd party source
vendor: ['react', 'redux', 'lodash']
},
output: {
path: path.join(__dirname, 'app', 'public', 'dist'),
publicPath: '/app/public/dist/',
filename: 'app.js'
},
module: {
loaders: [
{ test: /\.js$/, loaders: ['react-hot', 'babel'], exclude: /node_modules/ },
{ test: /.jsx?$/, loader: 'babel-loader', exclude: /node_modules/ },
{ test: /\.css/, loader: ExtractTextPlugin.extract('css') },
{ test: /\.scss$/, loader: ExtractTextPlugin.extract('!css!sass?sourceMap') }
]
},
sassLoader: {
includePaths: [ path.resolve(__dirname, './app/public/sass/')]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new webpack.optimize.CommonsChunkPlugin("vendor", "vendor.js", Infinity),
new ExtractTextPlugin('./css/style.css',{
allChunks: true
})
],
debug: true,
//watch: true
};

Resources