Pass JSON to pug template - javascript

I can't figure out how to access JSON data in my pug templates.
Here is my pug layout
title #{htmlWebpackPlugin.pages[page].title}
Pug page which is initializing page variable
block vars
- var page = "catalog"
Webpack part
new HtmlWebpackPlugin({
filename: 'catalog.html',
chunks: ['main'],
template: PATHS.source + '/views/pages/catalog.pug',
inject: true,
data: {
pages: require('./dev/util/options.json')
}
})
JSON
"pages": {
"catalog": {
"title": "Catalog",
"description": "",
"keywords": ""
}
}

Each page is a separate pug and json.
First, I declare the entry, in my case it is a separate js file entry.js
module.exports.html = {
     'index': 'index',
     'about': 'o-mnie',
     'contact': 'kontakt'
};
Webpack part
Include entry:
const entry = require('./entry.js');
Next add entry to HtmlWebpackPlugin:
const entryHtmlPlugins = Object.keys(entry.html).map(entryName => {
return new HtmlWebpackPlugin({
filename: `${entry.html[entryName]}.html`,
template: `./source/templates/containers/${entryName}/${entryName}.pug`,
chunks: [entryName],
file: require(`../source/templates/containers/${entryName}/${entryName}.json`)
})
});
See the full code how to use json data from pug and webpack -> github
const webpack = require("webpack");
const path = require('path');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const SimpleProgressWebpackPlugin = require('simple-progress-webpack-plugin');
const entry = require('./entry.js');
const entryHtmlPlugins = Object.keys(entry.html).map(entryName => {
return new HtmlWebpackPlugin({
filename: `${entry.html[entryName]}.html`,
template: `./source/templates/containers/${entryName}/${entryName}.pug`,
path: path.join(__dirname, "../dist/"),
chunks: [entryName],
// inject: true,
// cache: true,
file: require(`../source/templates/containers/${entryName}/${entryName}.json`),
mode: 'development'
})
});
const output = {
path: path.resolve(__dirname, "source"),
filename: "[name].[hash].js",
publicPath: "/"
}
const config = {
devtool: "eval-source-map",
mode: "development",
entry: entry.site,
output: output,
module: {
rules: [
{
// JS
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
}
},
{
// CSS | SCSS
test: /\.(css|scss)$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [{
loader: 'css-loader'
},
{
loader: 'postcss-loader',
options: {
plugins: () => [require('autoprefixer')({
'browsers': ['> 1%', 'last 2 versions']
})],
}
},
{
loader: 'sass-loader'
},
{
loader: 'sass-resources-loader', // style-resources-loader then we can use sass, less, stylus
options: {
resources: [
path.resolve(__dirname, '../source/scss/main.scss')
]
},
}
]
})
},
{
// IMAGES
test: /\.(jpe?g|png|gif|svg)$/i,
loader: "file-loader"
},
{
// PUG
test: /\.pug$/,
loader: 'pug-loader',
options: {
pretty: true,
self: true
}
}
],
},
plugins: [
new SimpleProgressWebpackPlugin({
format: 'compact'
}),
new ExtractTextPlugin({
filename: '[name].[hash].css',
// disable: false,
allChunks: true
}),
new webpack.DefinePlugin({
PRODUCTION: JSON.stringify(false)
}),
].concat(entryHtmlPlugins)
};
module.exports = config;

Related

Webpack does not load manifest.json file in production build

I'm creating a PWA react application in which I configure the manifest.json file and serviceWroker.js file.
In the development mode, it works fine but when I create production build using webpack, manifest.json file does not load in the Build folder.
Does anyone know what's the issue?
Here is my webpack.config.js file
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const WebpackRTLPlugin = require('webpack-rtl-plugin');
const WebpackMessages = require('webpack-messages');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const del = require('del');
const webpack = require('webpack');
// theme name
const themeName = 'metronic';
// global variables
const rootPath = path.resolve(__dirname);
const distPath = rootPath + '/src';
const mainConfig = function() {
const isEnvDevelopment = false;
const isEnvProduction = true;
return {
mode: 'production',
stats: 'errors-only',
performance: {
hints: false
},
externals: [ 'jspdf', 'jspdf-autotable' ],
entry: './src/index.js',
output: {
// main output path in assets folder
path: path.resolve(__dirname, 'dist'),
// output path based on the entries' filename
// filename: '[name].js',
filename: isEnvProduction
? 'static/js/[name].[contenthash:8].js'
: isEnvDevelopment && 'static/js/bundle.js',
// TODO: remove this when upgrading to webpack 5
futureEmitAssets: true,
// There are also additional JS chunk files if you use code splitting.
chunkFilename: isEnvProduction
? 'static/js/[name].[contenthash:8].chunk.js'
: isEnvDevelopment && 'static/js/[name].chunk.js',
// We inferred the "public path" (such as / or /my-project) from homepage.
// We use "/" in development.
publicPath: '/artbot/app/'
},
resolve: { extensions: [ '.scss', '.css','.mjs','.jsx', '.js', '.json' ] },
optimization: {
minimize: true,
namedChunks: true,
nodeEnv: 'production',
removeAvailableModules: true,
removeEmptyChunks: true,
mergeDuplicateChunks: true,
minimizer: [ new OptimizeCssAssetsPlugin(), new TerserPlugin({ cache: true }) ],
splitChunks: {
chunks: "all"
}
},
plugins: [
// webpack log message
new WebpackMessages({
name: themeName,
logger: (str) => console.log(`>> ${str}`)
}),
new BundleAnalyzerPlugin(),
new webpack.optimize.AggressiveMergingPlugin(),
new HtmlWebpackPlugin({
title: 'Custom Template',
template: 'public/index.html',
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
}
}),
// create css file
new MiniCssExtractPlugin({
filename: 'static/css/[name].css'
}),
new WebpackRTLPlugin({
filename: 'static/css/[name].rtl.css',
minify: true
}),
{
apply: (compiler) => {
// hook name
compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {
(async () => {
await del.sync(distPath + '/sass/*.js', { force: true });
})();
});
}
}
],
module: {
rules: [
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
// exclude: /#babel(?:\/|\\{1,2})runtime/,
exclude: /node_modules/,
loader: require.resolve('babel-loader'),
options: {
babelrc: true,
plugins: [
[
require.resolve('babel-plugin-named-asset-import'),
{
loaderMap: {
svg: {
ReactComponent: '#svgr/webpack?-svgo,+titleProp,+ref![path]'
}
}
}
]
]
}
},
{
test: /\.css$/,
loader: 'css-loader'
},
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'resolve-url-loader',
options: {
removeCR: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
},
{
test: /\.(png|jpg|svg)$/,
loader: 'file-loader',
options: {
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]',
esModule: false
}
//loader: 'url-loader?limit=8192'
},
{
test: /\.(woff2|eot|ttf|woff)$/,
loader: 'url-loader'
},
{
test: /\.json$/,
loader: 'file-loader',
type: 'javascript/auto',
exclude: /node_modules/,
options: {
name: 'static/json/[name].[hash:8].[ext]'
}
},
{
test: /\.html$/i,
loader: 'html-loader'
}
]
}
};
};
module.exports = function() {
return [ mainConfig() ];
};

how to make webpack import polyfills only for a specific build?

I just managed to make webpack create two separete builds one for es5 and another for es6.
See below the config file:
const path = require("path");
const common = require("./webpack.common");
const merge = require("webpack-merge");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
var HtmlWebpackPlugin = require("html-webpack-plugin");
const es5Config = merge(common,{
mode: "production",
output: {
filename: "[name].[contentHash].bundle.es5.js",
path: path.resolve(__dirname, "dist")
},
optimization: {
minimizer: [
new OptimizeCssAssetsPlugin(),
new TerserPlugin(),
new HtmlWebpackPlugin({
template: "./src/template.html",
minify: {
removeAttributeQuotes: true,
collapseWhitespace: true,
removeComments: true
}
}),
]
},
plugins: [
new MiniCssExtractPlugin({ filename: "[name].[contentHash].css" }),
new CleanWebpackPlugin(),
],
module: {
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader, //3. Extract css into files
"css-loader", //2. Turns css into commonjs
"sass-loader" //1. Turns sass into css
]
},
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
['#babel/preset-env', {
modules: false,
useBuiltIns: 'entry',
targets: {
browsers: [
"IE 11"
],
},
}],
],
},
},
}],
},
});
const es6Config = merge(common, {
mode: "production",
output: {
filename: "[name].[contentHash].bundle.es6.js",
path: path.resolve(__dirname, "dist")
},
optimization: {
minimizer: [
new OptimizeCssAssetsPlugin(),
new TerserPlugin(),
new HtmlWebpackPlugin({
template: "./src/template.html",
minify: {
removeAttributeQuotes: true,
collapseWhitespace: true,
removeComments: true
}
}),
]
},
plugins: [
new MiniCssExtractPlugin({ filename: "[name].[contentHash].css" }),
new CleanWebpackPlugin(),
],
module: {
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader, //3. Extract css into files
"css-loader", //2. Turns css into commonjs
"sass-loader" //1. Turns sass into css
]
},
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
['#babel/preset-env', {
modules: false,
useBuiltIns: "usage",
targets: {
browsers: [
'Chrome >= 60',
'Safari >= 10.1',
'iOS >= 10.3',
'Firefox >= 54',
'Edge >= 15',
],
},
}],
],
},
},
}],
},
});
module.exports = [es5Config, es6Config];
The issue is now that I wanted webpack to import the polyfills only for the es5 build. and use usebuilins set to usage did not work to polyfill anything.
Am I probably using it wrong maybe something related to the the node_modules package??
So I am just importing the polyfills in the main file like:
import "core-js/stable";
import "regenerator-runtime/runtime";
How can I make these imports to be added only for the es5 build? Or how can I include polyfills/imports from webpack?
And extra question if anyone knows, how can I use the usebuiltins with "usage" correctly? Cause so far even thought the polifylls are added for my main file I still get errors for Symbols in IE11, for example.
I figured it out. here is the webpack config:
common:
const path = require("path");
module.exports = {
entry: {
main: "./src/index.js",
vendor: "./src/vendor.js"
},
module: {
rules: [
{
test: /\.html$/,
use: ["html-loader"]
},
{
test: /\.(svg|png|jpg|gif)$/,
use: {
loader: "file-loader",
options: {
name: "[name].[hash].[ext]",
outputPath: "imgs"
}
}
}
]
}
};
prod:
const path = require("path");
const common = require("./webpack.common");
const merge = require("webpack-merge");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
var HtmlWebpackPlugin = require("html-webpack-plugin");
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
const es5Config = merge(common,{
mode: "production",
output: {
filename: "[name].[contentHash].bundle.es5.js",
path: path.resolve(__dirname, "dist")
},
optimization: {
runtimeChunk: 'single',
splitChunks: {
chunks: 'all',
maxInitialRequests: Infinity,
minSize: 0,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: (module) => {
// get the name. E.g. node_modules/packageName/not/this/part.js
// or node_modules/packageName
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
// npm package names are URL-safe, but some servers don't like # symbols
return `npm.${packageName.replace('#', '')}`;
},
},
},
},
minimizer: [
new OptimizeCssAssetsPlugin(),
new TerserPlugin(),
new HtmlWebpackPlugin({
filename: 'main.aspx',
template: "./src/main.html",
// minify: {
// removeAttributeQuotes: true,
// collapseWhitespace: true,
// removeComments: true
// }
}),
]
},
plugins: [
new MiniCssExtractPlugin({ filename: "[name].[contentHash].css" }),
new CleanWebpackPlugin(),
new BundleAnalyzerPlugin(),
],
module: {
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader, //3. Extract css into files
"css-loader", //2. Turns css into commonjs
"sass-loader" //1. Turns sass into css
]
},
{
test: /\.m?js$/,
exclude: /node_modules/,
//exclude: /node_modules\/(?!(\#pnp)\/).*/,
use: {
loader: 'babel-loader',
options: {
//configFile : './es5.babel.config.json',
presets: [
['#babel/preset-env', {
modules: false,
useBuiltIns: false,
targets: {
browsers: [
"IE 11"
],
},
}],
],
},
},
}],
},
});
const es6Config = merge(common, {
mode: "production",
output: {
filename: "[name].[contentHash].bundle.es6.js",
path: path.resolve(__dirname, "dist")
},
optimization: {
runtimeChunk: 'single',
splitChunks: {
chunks: 'all',
maxInitialRequests: Infinity,
minSize: 0,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: (module) => {
// get the name. E.g. node_modules/packageName/not/this/part.js
// or node_modules/packageName
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
// npm package names are URL-safe, but some servers don't like # symbols
return `npm.${packageName.replace('#', '')}`;
},
},
},
},
minimizer: [
new OptimizeCssAssetsPlugin(),
new TerserPlugin(),
new HtmlWebpackPlugin({
filename: 'main_es6.html',
template: "./src/main.html",
// minify: {
// removeAttributeQuotes: true,
// collapseWhitespace: true,
// removeComments: true
// }
}),
]
},
plugins: [
new MiniCssExtractPlugin({ filename: "[name].[contentHash].css" }),
new CleanWebpackPlugin(),
],
module: {
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader, //3. Extract css into files
"css-loader", //2. Turns css into commonjs
"sass-loader" //1. Turns sass into css
]
},
],
},
});
module.exports = [ es5Config, es6Config];
babel.config.json:
{
"plugins": [
[
"#babel/plugin-transform-runtime",
{
"absoluteRuntime": true,
"helpers": true,
"regenerator": true,
"useESModules": false
}
]
]
}
so this combined with the cdn polyfill works to load the polifylls only for IE11. it also has it's own build.
The only issue here is that the resulting output will have separated files and the es5 build should have nomodule in all it's scripts. Also for the es6 all should have module.
I then have to go and manually add those which I can easily make a custom template to handle that.
But then the scripts for the polyfill is removed and I still have to manually merge the html files. Anyone knows how to handle that?
edit:
1 - for the attributes you can use HtmlWebpackPlugin hooks () or ScriptExtHtmlWebpackPlugin to place the attributes in the tags.
find some code with hooks here:
const HtmlWebpackPlugin = require('html-webpack-plugin');
class es5TagTransformerHook {
apply (compiler) {
compiler.hooks.compilation.tap('MyPlugin', (compilation) => {
HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups.tapAsync(
'es5TagTransformerHook', stacktraces
async (data, cb) => {
// Manipulate the content
// data.html += 'The Magic Footer'
// Tell webpack to move on
data.bodyTags.forEach(t=>t.tagName === 'script'?t.attributes.nomodule = true:null)
cb(null, data)
}
)
})
}
}
module.exports = es5TagTransformerHook
2 - for merging the resulting html I ended up using this gist:
https://gist.github.com/agoldis/21782f3b9395f78d28dce23e3b6ddd56

The Dynamic import for angularjs + webpack

I'm trying to implement Webpack4 for the angularjs project. I created some entrypoints and as for static imports they works as it's expected. But in the project we have some landing pages and their folders with the same names ('1300', '1520') etc that includes landing page css and html files. So if we use url like '...?theme=1520' the html and css from the '1520' folder are used(along with general styles and html). Now I have 3 webpack bundles for custom js, vendor js, general css.
So I try to import the landing page css and html dynamically depending on the url parameter. Of course, it doesn't work even after using all the plugins and solutions that I could find everywhere. The main goal now is to insert landing page css styles dynamically into the css bundle(in css.js). Thanks!
webpack.config.js:
const webpack = require("webpack");
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const cssnano = require('cssnano');
const TerserPlugin = require('terser-webpack-plugin');
const ImageminWebpWebpackPlugin = require("imagemin-webp-webpack-plugin");
const { nodeName } = require("jquery");
module.exports = {
target: 'node',
//mode: 'production',
context: path.resolve(__dirname, 'WebContent'),
entry: {
custom: './js/app.js',
styles: './js/css.js',
vendor: './js/vendor.js'
},
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].bundle.js'
//,publicPath: 'build'
},
plugins: [new MiniCssExtractPlugin(),
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.bundle\.css$/g,
cssProcessor: cssnano,
cssProcessorPluginOptions: {
preset: ['default', { discardComments: { removeAll: true } }],
},
canPrint: false
}),
new ImageminWebpWebpackPlugin(),
],
module: {
rules: [
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env'],
plugins: ['#babel/plugin-syntax-dynamic-import']
}
}
},
{
test: /\.html$/i,
loader: 'html-loader',
},
{
test: /\.css$/,
exclude: /node_modules/,
use: [{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: './WebContent',
esModule: true
}
}, {
loader: 'css-loader',
options: {
import: true,
//modules: true
}
}]
},
{
test: /\.(gif|png|jpe?g|svg)$/,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/',
publicPath: path.resolve(__dirname, './build/images/'),
//emitFile: false
}
},
'url-loader?limit=100000']
}
]
},
optimization: {
splitChunks: {
// chunks: 'all',
cacheGroups: {
styles: {
name: 'styles.bundle',
test: /\.css$/,
chunks: 'all',
enforce: true,
minChunks: 1
}
}
}
,
minimize: true,
minimizer: [new TerserPlugin({
extractComments: false,
exclude: /\/node_modules/,
terserOptions: {
keep_fnames: true,
mangle: false
},
})]
}
};
css.js:
var BORDER_SCREEN_WIDTH_VALUE = 768;
var device = 'mobile';
var path = '';
var lpNumber = new RegExp('[\?&]theme=([^&#]*)').exec(window.location.search)[1];
if (window.innerWidth > BORDER_SCREEN_WIDTH_VALUE) {
device = 'desktop';
}
path = '/' + lpNumber + '/' + device + '/';
console.log(path);
import(/* webpackIgnore: true */'../WebContent/LP' + path + 'style.css').then((module) => {
module();
});
require('../css/amazing-theme.min.css');
require('../css/general.min.css');
require('../css/leadgen-theme.min.css');
require('../css/partials.min.css');
require('../css/style-all.min.css');
//require('../LP/1138/desktop/style.css');

url() in SCSS won't resolve correctly with Webpack 4

I have posted my Webpack configs below for a production environment. I am attempting to use background-image: url(../img/chevron-thin-right.svg); in one of my SCSS files but it is being resolved to background-image: url([object Module]) and therefore not working. I am trying to port a purely SCSS and HTML project into a react app being bundled by Webpack so this above approach used to work. Any fixes would be greatly appreciated.
webpack.common.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const outputDirectory = 'dist';
module.exports = {
entry: './src/client/index.js',
output: {
path: path.join(__dirname, outputDirectory),
filename: 'bundle.js'
},
plugins: [
new HtmlWebpackPlugin({
title: 'Production',
template: './public/index.html',
favicon: './public/favicon.ico',
hash: true,
filename: 'index.html'
})
],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.(jpg|png|woff|woff2|eot|ttf)$/,
use: {
loader: 'file-loader?limit=100000&name=images/[name].[ext]'
}
},
{
test: /\.svg$/,
use: [
"babel-loader",
{
loader: "react-svg-loader",
options: {
svgo: {
plugins: [
{
removeTitle: true,
removeComments: true
}
],
floatPrecision: 2
}
}
}
]
}
]
}
};
webpack.prod.js
const merge = require('webpack-merge');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const common = require('./webpack.common.js');
const path = require('path');
const autoprefixer = require('autoprefixer');
module.exports = {};
module.exports = merge(common, {
mode: 'production',
optimization: {
splitChunks: {
cacheGroups: {
styles: {
name: 'styles',
test: /\.css$/,
chunks: 'all',
enforce: true
}
}
}
},
plugins: [
new CleanWebpackPlugin(['dist']),
new MiniCssExtractPlugin({
filename: '[name].css'
})
],
module: {
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: true,
root: path.resolve(__dirname),
},
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
autoprefixer({
'browsers': ['last 2 versions', 'ie >= 10'],
}),
],
sourceMap: true,
},
},
{
loader: 'sass-loader',
options: {
outputStyle: 'compressed',
sourceMap: true,
includePaths: [
'./src/client/style/scss',
],
},
}
]
}
]
}
});
In case anybody else is looking for an answer I was able to solve it. It was due to not loading the associated SVG through the url-loader. Another problem arose when adding svg back in because my inline SVGs I wanted to use as React components were running into errors as they were now going through the url-loader instead of my react-svg-loader.
Below is the working webpack.common.js and webpack.prod.js stayed the same. The solution was to differentiate my inline and external SVGs by turning all inline extensions from .svg to .inline.svg and adjusting webpack config accordingly
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const outputDirectory = 'dist';
module.exports = {
entry: './src/client/index.js',
output: {
path: path.join(__dirname, outputDirectory),
filename: 'bundle.js'
},
plugins: [
new HtmlWebpackPlugin({
title: 'Production',
template: './public/index.html',
favicon: './public/favicon.ico',
hash: true,
filename: 'index.html'
})
],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.(jpg|png|woff|woff2|eot|ttf|svg)$/,
exclude: /\.inline.svg$/,
use: {
loader: 'url-loader?limit=1000&name=images/[name].[ext]'
}
},
{
test: /\.inline.svg$/,
use: [
"babel-loader",
{
loader: "react-svg-loader",
options: {
svgo: {
plugins: [
{
removeTitle: true,
removeComments: true
}
],
floatPrecision: 2
}
}
}
]
}
]
}
};

Webpack is creating test and snapshot bundles

I've recently tried to add proper code splitting for the first time to one of my projects.
It's worked, however I think it's worked a little TOO well!
When I run bundle-analyser, my dist folder contains a bunch of other bundles that contain snapshots and test files and I can't find any information that would explain why this is happening!
here is my webpack.config.base.js
const path = require('path');
const postcssNested = require('postcss-nested');
const postcssSimpleVars = require('postcss-simple-vars');
const postcssPresetEnv = require('postcss-preset-env');
const postcssImport = require('postcss-import');
const postcssFor = require('postcss-for');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractCssPluginConfig = new ExtractTextPlugin({
filename: '[name].[hash].css',
disable: false,
});
const HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html',
inject: 'body',
});
module.exports = {
entry: {
main: './src/index.jsx',
},
output: {
path: path.resolve('_dist'),
chunkFilename: '[name].[hash].bundle.min.js',
filename: '[name].[hash].min.js',
publicPath: '/',
},
module: {
rules: [
{
test: /\.(js|jsx)?$/,
loader: 'babel-loader',
exclude: /node_modules\/(?!(dom7|ssr-window|swiper)\/).*/,
},
{
test: /\.css$/,
loader: 'style-loader',
},
{
test: /\.css$/,
loader: 'css-loader',
query: {
modules: true,
importLoaders: 1,
localIdentName: '[path]___[name]__[local]___[hash:base64:5]',
},
},
{
test: /\.css$/,
loader: 'postcss-loader',
options: {
plugins: () => [
postcssNested,
postcssImport,
postcssFor,
postcssPresetEnv({
browsers: '>1%',
autoprefixer: {
grid: true,
browsers: ['>1%'],
},
insertBefore: {
'all-property': postcssSimpleVars,
},
}),
],
},
},
{
test: /\.(png|jp(e*)g|svg)$/,
use: [{
loader: 'url-loader',
options: {
limit: 8000,
name: 'images/[hash]-[name].[ext]',
},
}],
},
{
test: /\.(woff|woff2|ttf|eot|otf)$/,
use: 'file-loader?name=fonts/[name].[ext]',
},
{
test: /\.(pdf)$/,
use: [{
loader: 'url-loader',
options: { limit: 8000, name: 'documents/[hash]-[name].[ext]' },
}],
},
],
},
resolve: {
extensions: ['.js', '.jsx', '.css', '.svg'],
modules: [path.resolve('./node_modules')],
alias: {
Pages: path.resolve(__dirname, 'src/pages/'),
Sections: path.resolve(__dirname, 'src/sections/'),
Components: path.resolve(__dirname, 'src/components/'),
Images: path.resolve(__dirname, 'src/images/'),
Downloads: path.resolve(__dirname, 'src/downloads/'),
Services: path.resolve(__dirname, 'src/services/'),
Enum: path.resolve(__dirname, 'src/enum/'),
Data: path.resolve(__dirname, 'src/data/'),
Utils: path.resolve(__dirname, 'src/utils/'),
Config: path.resolve(__dirname, 'src/config/'),
},
},
plugins: [
ExtractCssPluginConfig,
HtmlWebpackPluginConfig,
],
};
and here is my webpack.config.build.js
const webpack = require('webpack');
const merge = require('webpack-merge');
const WebpackCleanupPlugin = require('webpack-cleanup-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const baseConfig = require('./webpack.config.base');
const WebpackCleanupPluginConfig = new WebpackCleanupPlugin({
exclude: ['webpack.stats.json'],
quiet: true,
});
const CopyWebpackPluginConfig = new CopyWebpackPlugin([
{ from: './src/documents', to: './documents' },
]);
module.exports = () => {
const DefinePluginConfig = new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production'),
});
return (
merge(baseConfig, {
optimization: {
runtimeChunk: 'single',
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'initial',
enforce: true,
},
},
},
noEmitOnErrors: true,
concatenateModules: true,
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: false,
}),
],
},
plugins: [
DefinePluginConfig,
WebpackCleanupPluginConfig,
CopyWebpackPluginConfig,
],
})
);
};
I've tried adding a regex that matches any files with .test.js/jsx and .snap to my module.rules object but that did nothing.
Any help would be greatly appreciated!
If your test files are in a different directory, you might want to consider adding exclude property within the modules rules for js files.
Refer the following document: https://webpack.js.org/configuration/module/?_sm_au_=iVVKrMW7ZsbHQPbq#rule-exclude
or the following example: https://webpack.js.org/configuration/?_sm_au_=iVVKrMW7ZsbHQPbq#options
Another solution would be to use the IgnorePlugin. Docs for IgnorePlugin here: https://webpack.js.org/plugins/ignore-plugin/?_sm_au_=iVVKrMW7ZsbHQPbq

Categories