WebPack Cache busting hash in file names never changes - gulp

I am trying to get cache busting in my gulp file output to work. Currently it outputs a file like this: main.2d06434c1c57525870ac-e7615836.js but whenever I modify typescript files and rebuild the hash in the file name output is always the same.
I have tried the built in webpack hashing and the gulp vinyl-named hashing to see if there was something wrong with one of their configurations but again their output filename is the same on each rebuild.
Here is the related part of my builder task. Thanks!
var packer = gulp.src(['./src/basePolyfills.ts', './src/external.ts', './src/main.ts'])
.pipe(named())
.pipe(webpack({
output: { filename: '[name].[hash].js' },
module: {
loaders: [
{ test: /\.ts$/, loader: 'ts' },
{ test: /\.html$/, loader: 'html' }
]
},
resolve: { extensions: ['', '.js', '.ts'] }
}))
.pipe(hash())
.pipe(gulp.dest('./wwwroot/js/'));

Where is your hash() coming from? As far as I know, webpack automatically calculates chunkhashes. Be aware that there is a difference between "hash" and "chunkhash". chunkhash is a hash per chunk, whereas "hash" seems to be a hash over all files.
Can you try:
var packer = gulp.src(['./src/basePolyfills.ts', './src/external.ts', './src/main.ts'])
.pipe(named())
.pipe(webpack({
output: { filename: '[name].[chunkhash].js' },
module: {
loaders: [
{ test: /\.ts$/, loader: 'ts' },
{ test: /\.html$/, loader: 'html' }
]
},
resolve: { extensions: ['', '.js', '.ts'] }
}))
.pipe(gulp.dest('./wwwroot/js/'));

Related

Using Webpack to Handle Image Directory

I am currently switching a web app to have its assets bundled using Webpack. Bundling JS and CSS was somewhat straightforward. Then came the turn of images. My question is how one can approach bundling images.
In particular, suppose I have static_src from which everything originates and static_compiled into which the bundled output is placed. I would like the image contents of static_src/img to move into static_compiled/img. How does one accomplish this?
On another note, is this a sensible approach or am I misunderstanding some philosophy behind Webpack and misusing it?
Current config is roughly like this:
var webpack = require('webpack')
var BundleTracker = require('webpack-bundle-tracker')
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
entry: { index: path.resolve(__dirname, "static_src", "index.js") },
output: {
path: path.resolve(__dirname, "static_compiled"),
publicPath: "/static/", // Should match Django STATIC_URL
filename: "[name].js", // No filename hashing, Django takes care of this
chunkFilename: "[id]-[chunkhash].js", // DO have Webpack hash chunk filename, see below
},
plugins: [
new BundleTracker({filename: './webpack-stats.json'}),
],
module: {
rules: [
{
test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel-loader'}, // to transform JSX into JS
{
test: /\.scss$/, use: ["style-loader", "css-loader", "sass-loader"]},
{
test: /\.css$/, use: ["style-loader", "css-loader"]},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
loader: 'file-loader'},
{
test: /\.svg$/,
loader: 'svg-inline-loader'},
/* {
test: /\.(ico|png|jpg|gif)$/,
loader: 'file-loader'} */
{
test: /\.(ico|png|svg|jpg|gif|jpe?g)$/,
use: [
{
options: {
name: "[name].[ext]",
outputPath: "img/"
},
loader: "file-loader"
}
]
}
],
},
resolve: {
alias: {
shared: path.resolve(__dirname, 'node_modules', 'bower_components')
},
extensions: ['.js', '.ts', 'jsx', 'tsx']
},
devServer: {
writeToDisk: true, // Write files to disk in dev mode, so Django can serve the assets
}
}
The code I ended up using looks something like this.
plugins section:
plugins: [...
new CopyPlugin({
patterns: [
{
from: path.resolve(__dirname, `static_src/img`),
to: 'img',
}
]
}),
module-rules section:
module: {
rules: [
{ ...
test: /\.(ico|png|jpg|gif|jpe?g)$/,
use: [
{
loader: "file-loader",
options: {
name: "[name].[ext]",
outputPath: "img/"
}
}
]
}

Webpack 4 html partials resolve images in files

I am new to webpack, I followed directions in this link https://github.com/hardikkaji/angularjs-es6-starter-kit
I am using webpack 4 with angular 1.7
I am not able to resolve images.
ERROR in ./node_modules/angular-datatables/demo/basic/overrideLoadingTpl.html
Module not found: Error: Can't resolve './images/loading.gif' in '/home/user/workspace/webpack/angular-webpack/node_modules/angular-datatables/demo/basic'
My webpack.config.js is below
const config = {
mode: devMode ? 'development' : 'production',
entry: {
'vendor': './frontend/vendor.module.js', //seperates all 3rd party plugins like ui-router, retstangualr etc
'app': './frontend/index.main.js' //main entry point for angular js
},
devtool: devMode ? 'source-map': 'none',
output: {
filename: elixirConfig.js.outputFolder + '/[name].[hash].bundle.js',
//filename: 'libs/[name].[hash].bundle.js', //where to store the generated files all files will be generated inside a folder called libs
//path: path.resolve(__dirname, 'build')
path: path.resolve(__dirname, elixirConfig.buildPath)
},
module: {
rules: [
{
test: /.js$/, //check for file that ends with .js extension
exclude: /node_modules/, //do not check for files inside node_modules folder
loader: ['ng-annotate-loader', 'babel-loader'],
//presets: ['es2016'],
},
{
test: /.(scss)$/, //check for files that end with scss
use: [
devMode ? { loader: "style-loader" } : MiniCssExtractPlugin.loader,
{ loader: "css-loader", options: { minimize: true } },
{ loader: "sass-loader" },
]
},
// for fixing of loading bootstrap icon files
{
test: /.(png|jpg|jpeg|gif|svg|woff|woff2)$/,
loader: 'url-loader?limit=10000',
options: {
name: './fonts/[name].[ext]'
}
},
{
test: /.(woff(2)?|ttf|eot|svg)(\?v=\d+.\d+.\d+)?$/,
loader: 'file-loader',
options: {
name: './fonts/[name].[ext]'
}
},
{ test: /.html$/, include: /node_modules/, loader: 'html-loader' },
]
},

How to fix “Module build failed: SyntaxError: Unexpected token” error when using JSON file in react?

I am following a react tutorial by Brian holt and i need to import .json file inside my react component like this :
code
When I try to build my project i was getting
ERROR in ./data.json
Module build failed: SyntaxError: Unexpected token, expected
like this:
Error caption in terminal
at first i thought that it was an eslint issue but it seems that it happens on the build step, i tried adding a json-loader to webpack but without any success.
Webpack Version:
2.6.1
Babel Core Version:
6.24.1
Babel Loader Version:
7.0.0,
this is my webpack config file :
const path = require('path')
module.exports = {
context: __dirname,
entry: './js/clientApp',
devtool: 'cheap-eval-source-map',
output: {
path: path.join(__dirname, 'public'),
filename: 'bundle.js',
publicPath: '/assets/'
},
resolve: {
extensions: ['.js', '.jsx', ',json']
},
devServer: {
publicPath: '/public/',
port: 2110,
open: true,
historyApiFallback: true
},
stats: {
colors: true,
reasons: true,
chunks: true
},
module: {
rules: [
{
enforce: 'pre',
test: /\.jsx?/,
loader: 'eslint-loader',
exclude: /node_modules/
},
{
test: /\.jsx?/,
loader: 'babel-loader'
}
]
}
}
and this is my .babelrc file :
{
"presets": [
"react", ["env", {
"targets": {
"browsers": "last 2 versions"
},
"loose": true,
"modules": false
}]
]
}
Any suggestions please ?
Regular Expression
The test property identifies which file or files should be transformed.
The problem is the regular expression on your rules:
{ test: /\.jsx?/ }
Your telling webpack to use babel-loader with any file extension starting with .js or .jsx
So as you can see .json match the test.
Solution
$ - matches anything until the end of the string
To fix this just replace ? with $, see the example below:
module: {
rules: [
{
test: /\.jsx$/,
loader: 'babel-loader'
}
]
}

Webpack 3.9.1 - How do I combine LESS files into one CSS file?

I'm very new to Webpack and I'm not certain how to handle LESS. I want to have many LESS files and I want them to compile into one CSS file after I run npm run build. This would result in a style.css file which includes everything.
My webpack.config.js looks like this:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules:
[
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.less$/,
use: [{
loader: "style-loader", // creates style nodes from JS strings
path: path.resolve(__dirname, 'src')
}, {
loader: "css-loader", // translates CSS into CommonJS
path: path.resolve(__dirname, 'src')
}]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
},
{
test: /\.json$/,
loader: 'json-loader'
}
]
},
plugins: [new HtmlWebpackPlugin()]
};
How exactly do I configure webpack to make it combine all LESS files into one CSS file?
You can use a plugin called extract-text-webpack-plugin to achieve this. According to their documentation, this plugin moves all the required *.css modules in entry chunks into a separate CSS file. So your styles are no longer inlined into the JS bundle, but in a separate CSS file (styles.css). Now of course, in your case, you will first have to parse your .less files to .css and then bundle them up into a single file.
You can modify your webpack config like so:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
},
{
test: /\.less$/,
use: ExtractTextPlugin.extract({ <---- Use the plugin here to extract the styles
fallback: "style-loader",
use: "css-loader"
})
},
{
test: /\.(png|svg|jpg|gif)$/,
use: ['file-loader']
},
{
test: /\.json$/,
loader: 'json-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin(),
new ExtractTextPlugin("styles.css"),
]};
You can use extract-text-webpack-plugin to make one css file. But only do this for a production build not while you are developing.
I would look at using the Webpack less-loader. It covers a production build here

Raw loader with ES6 imports

I'm trying to use ES6 with webpack. Its okay for javascript module imports/exports, but I can't get raw-loader to work.
Here is what I am intending to do in my source file
import template from './template.html'
The template.html file has raw HTML in it.
module.exports = {
context: __dirname,
entry: [
'babel-polyfill',
'./app/app.js',
],
module: {
preLoaders: [
{
test: /\.js$/,
include: __dirname + '/app/',
loader: 'eslint-loader',
},
],
loaders: [
{
test: /\.js$/,
include: __dirname + '/app/',
loader: 'babel-loader?presets[]=es2015',
},
{
test: /\.html$/,
include: __dirname + '/app/',
loader: 'raw-loader',
},
],
},
output: {
path: './build/',
filename: 'app.js',
},
};
When I launch webpack, the code is generated as so:
module.exports = "module.exports = \" hello\\n <div>\\n <ul>\\n <li ng-repeat...
It should only be the "hello\n <div>..." string that should be exported.
Any help on this ? I really don't understand how to do this.
Import with raw-loader returns object with default property (import * as template from './file'). You can call it template.default to get what you want.
Here was the similar issue
And here you cant give a glance the way how you can update code of raw loader to use imported value as it is. Just have tinkered with this for a while