I am working on a large codebase; I have multiple src files to compile. When I run watch or compile for production it will compile all files found in src. Which is exactly what webpack should do.
But I would like to compile only the files which have been recently changed instead of all the files. Is this possible?
Here's my webpack config
const path = require("path");
const webpack = require("webpack");
const extractTextPlugin = require("extract-text-webpack-plugin");
const {VueLoaderPlugin} = require("vue-loader");
module.exports = {
entry: {
clients:
"./src/clients/Resources/vue-js/clients.js",
dashboard:
"./src/dashboard/Resources/vue-js/dashboard.js",
mapView:
"./src/mapView/Resources/vue-js/mapView.js",
admin:
"./src/admin/Resources/vue-js/admin.js"
},
output: {
path: path.join(__dirname, "./dist/"),
publicPath: "/dist/",
filename: "js/[name].js",
chunkFilename: "js/[name].js"
},
optimization: {
splitChunks: {
cacheGroups: {
vendors: {
name: "vendor",
filename: "js/vue_bundle.js",
automaticNameDelimiter: "_",
test: /[\\/]node_modules[\\/]/,
chunks: "all",
priority: 1,
minChunks: 2,
minSize: 0
},
}
},
occurrenceOrder: true,
},
module: {
rules: [
{
test: /\.vue$/,
loader: "vue-loader"
},
{
test: /\.js$/,
loader: "babel-loader",
exclude: /node_modules/,
options: {
presets: ["env"]
}
},
{
test: /\.(png|woff|woff2|eot|ttf|svg)$/,
loader: "url-loader?limit=100000"
},
{
test: /\.css$/,
use: extractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
},
{
test: /\.scss$/,
use: extractTextPlugin.extract({
// use: ['raw-loader', 'sass-loader']
use: "raw-loader!sass-loader"
})
},
{
test: /\.sass$/,
use: extractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader!sass-loader"
})
},
{
test: /\.jpe?g$|\.ico$|\.gif$|\.png$|\.svg$|\.woff$|\.ttf$|\.wav$|\.mp3$/,
loader: "file-loader?name=[name].[ext]"
},
{
test: /\.yaml$/,
loader: "json-loader!yaml-loader"
}
]
},
plugins: [
new extractTextPlugin({
filename: "css/[name].css",
allChunks: true
})
]
};
Related
I moved a React app from create-react-app to Webpack 5 and the UI library, Ant Design, is no longer loading the icons on components.
For several components, this is having functionality breaking effects.
Issue
When attempting to use a component that has an icon, it will console.log the below error message and render the component without that icon.
Error Message
warning.js:16 Warning: [#ant-design/icons] icon should be icon definiton, but got:
var LeftOutlined={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"}}]},name:"left",theme:"outlined"};export default LeftOutlined;
Webpack
const HtmlWebpackPlugin = require('html-webpack-plugin')
const path = require('path')
module.exports = {
entry: './src/index.tsx',
output: {
filename: 'index.min.js',
path: path.resolve(__dirname, '../public/'),
},
resolve: {
modules: [__dirname, 'src', 'node_modules'],
extensions: ['*', '.js', '.jsx', '.tsx', '.ts', '.less'],
},
plugins: [
new HtmlWebpackPlugin({
template: './index.html',
}),
],
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: require.resolve('babel-loader'),
},
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.less$/i,
use: ['style-loader', 'css-loader', 'less-loader'],
},
{
test: /\.svg$/,
use: [
{
loader: 'svg-url-loader',
options: {},
},
],
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'babel-loader',
},
{
loader: '#svgr/webpack',
options: {
babel: false,
icon: true,
},
},
],
},
{
test: /\.png|svg|jpg|gif$/,
use: ['file-loader'],
},
],
},
}
Babel
{
"presets": ["#babel/preset-react", "#babel/preset-env"],
"plugins": [["#babel/transform-runtime"]]
}
I am using React Application. Below is my Webpack Configuration file for 5.47.1.
const path = require('path');
const webpack = require('webpack');
process.noDeprecation = true;
module.exports = (options) => ({
entry: options.entry,
output: Object.assign({ // Compile into js/build.js
path: path.resolve(process.cwd(), 'build'),
publicPath: '/',
}, options.output), // Merge with env dependent settings
module: {
mode: 'development',
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: options.babelQuery,
},
},
{
test: /\.scss$/,
exclude: /node_modules/,
use: ['style-loader', 'css-loader', 'sass-loader'],
},
{
test: /\.css$/,
exclude: /node_modules/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.css$/,
include: /node_modules/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(eot|svg|otf|ttf|woff|woff2)$/,
use: 'file-loader',
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
'file-loader',
{
loader: 'image-webpack-loader',
options: {
progressive: true,
optimizationLevel: 7,
interlaced: false,
pngquant: {
quality: '65-90',
speed: 4,
},
},
},
],
},
{
test: /\.html$/,
use: 'html-loader',
},
{
test: /\.json$/,
use: 'json-loader',
},
{
test: /\.(mp4|webm)$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
},
},
},
],
},
plugins: options.plugins.concat([
new webpack.ProvidePlugin({
// make fetch available
fetch: 'exports-loader?self.fetch!whatwg-fetch',
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV' : JSON.stringify('development'),
}),
// new webpack.NamedModulesPlugin(),
]),
resolve: {
modules: ['app', 'node_modules'],
extensions: [
'.js',
'.jsx',
'.react.js',
],
mainFields: [
'browser',
'jsnext:main',
'main',
],
},
devtool: options.devtool,
target: 'web', // Make web variables accessible to webpack, e.g. window
performance: options.performance || {},
});
I have updated mode. Could not figure out the config issues here
mode should be in the root object and not in the module object:
module.exports = (options) => ({
mode: 'development',
entry: options.entry,
output: Object.assign({ // Compile into js/build.js
path: path.resolve(process.cwd(), 'build'),
publicPath: '/',
}, options.output), // Merge with env dependent settings
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: options.babelQuery,
},
},
{
test: /\.scss$/,
exclude: /node_modules/,
use: ['style-loader', 'css-loader', 'sass-loader'],
},
{
test: /\.css$/,
exclude: /node_modules/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.css$/,
include: /node_modules/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(eot|svg|otf|ttf|woff|woff2)$/,
use: 'file-loader',
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
'file-loader',
{
loader: 'image-webpack-loader',
options: {
progressive: true,
optimizationLevel: 7,
interlaced: false,
pngquant: {
quality: '65-90',
speed: 4,
},
},
},
],
},
{
test: /\.html$/,
use: 'html-loader',
},
{
test: /\.json$/,
use: 'json-loader',
},
{
test: /\.(mp4|webm)$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
},
},
},
],
},
plugins: options.plugins.concat([
new webpack.ProvidePlugin({
// make fetch available
fetch: 'exports-loader?self.fetch!whatwg-fetch',
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development'),
}),
// new webpack.NamedModulesPlugin(),
]),
resolve: {
modules: ['app', 'node_modules'],
extensions: [
'.js',
'.jsx',
'.react.js',
],
mainFields: [
'browser',
'jsnext:main',
'main',
],
},
devtool: options.devtool,
target: 'web', // Make web variables accessible to webpack, e.g. window
performance: options.performance || {},
});
So I tried creating a boilerplate for an existing project that our company have and after running the script for webpack,
it generated a ./dist/server.js however, when I run it from node, I am getting this document not found error. Please let me know if you need a code snippet of a specific file.
ERROR
){var n=(0,r.renderToString)(o().createElement(Wn,null));a.send('\n <!DOCTYPE html>\n <html>\n <head>\n </head>\n <body style="margin:0">\n <div id="root">'+n+'</div>\n </body>\n <script src="main.bundle.js" defer><\/script>\n </html>\n')})),Hn.listen(3e3,(function(){console.log("app listening on port 3000!")}))})()})();
ReferenceError: document is not defined
code above is a long one line code which I had to cut off
webpack.config.client.js
const path = require('path');
module.exports = {
mode: 'production',
entry: {
main: './src/index.tsx',
},
module: {
rules: [
{
loader: 'ts-loader',
test: /\.(tsx|ts)?$/,
exclude: [/node_modules/],
},
{
test: /\.(scss)$/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loader: 'file-loader',
options: {
name: '/src/assets/images/[name].[ext]'
}
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
loader: "file-loader"
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
output: {
filename: '[name].bundle.js',
sourceMapFilename: '[file].map',
path: path.resolve(__dirname, 'dist/public'),
},
};
webpack.config.server.js
const path = require('path');
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const nodeExternals = require('webpack-node-externals');
const { join } = require('lodash');
module.exports = {
mode: 'production',
entry: {
server: './server/index.tsx',
},
target: 'node',
node: {
__dirname: false,
__filename: false,
},
externals: [nodeExternals()],
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
title: "Test",
template: './src/index.html'
})
],
module: {
rules: [
{
loader: 'ts-loader',
test: /\.tsx?$/,
options: {
transpileOnly: true,
},
exclude: [/node_modules/],
},
{
test: /\.(s*)css$/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loader: 'file-loader',
options: {
name: '/src/assets/images/[name].[ext]'
}
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
loader: "file-loader"
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
},
};
I'm migrating a react website to webpack 4 (from 3) but have been running into some strange problems when using webpack for css.
It works fine for the css that I wrote myself, but any css from third party components in node_modules does not seem to be included at all.
Here is an example of my webpack config:
const webpack = require('webpack');
const path = require('path');
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const config = {
entry: [
'react-hot-loader/patch',
'./src/index.js'
],
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js'
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.css$/,
exclude: [/node_modules/, /global\.css$/],
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: true,
}
},
'postcss-loader'
]
},
{
test: /\.css$/,
include: [/node_modules/, /global\.css$/],
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 0,
modules: true,
}
}
]
},
{
test: /\.png$/,
use: [
{
loader: 'url-loader',
options: {
mimetype: 'image/png'
}
}
]
},
{
test: /\.svg$/,
use: 'file-loader'
},
{
test: /\.jpg$/,
use: [
{
loader: 'url-loader',
options: {
mimetype: 'image/jpg'
}
}
]
},
]
},
resolve: {
extensions: [
'.js',
'.jsx'
],
alias: {
'react-dom': '#hot-loader/react-dom'
},
modules: [
'node_modules',
],
},
devServer: {
contentBase: './dist'
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
}),
new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en/),
new LodashModuleReplacementPlugin,
new HtmlWebpackPlugin({
template: require('html-webpack-template'),
inject: false,
appMountId: 'app',
})
],
optimization: {
runtimeChunk: 'single',
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
};
module.exports = (env, argv) => {
if (argv.hot) {
// Cannot use 'contenthash' when hot reloading is enabled.
config.output.filename = '[name].[hash].js';
}
return config;
};
Only css from my own files are included in the generated bundle.
I'm using the latest versions:
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.9.0"
Greatful for any help!
Layout of the project
I create a project with the following structure:
Webpack 4 configuration:
const HtmlWebPackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
output: {
path: __dirname + '/web'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: ['babel-loader', 'eslint-loader']
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
options: { minimize: true }
}
]
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
{
test: /\.scss$/,
exclude: /node_modules/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: __dirname + '/fonts'
}
}]
},
{
test: /\.(jpg|png)$/,
use: {
loader: "file-loader",
options: {
name(file) {
if (env === 'development') {
return './images/[name].[ext]'
}
return '[hash].[ext]'
}
}
}
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: './src/index.html',
filename: './index.html'
}),
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css'
})
]
};
After compilation, the main.js, main.css and index.html are placed in the web folder. How to make all the pictures in the project copied to the web/images, and the fonts in the web/fonts?
In the project, I refer to them as follows:
1) src\Interface\Header\Index.js
<img src="img/logo.png" srcSet="img/logo#2x.png 2x, img/logo#3x.png 3x" className="header-logo" alt=""/>
2) src\Pages\App\style.css
#font-face {
font-family: 'HelveticaNeueCyr';
src: url('/fonts/HelveticaNeueCyr.woff2') format('woff2'),
url('/fonts/HelveticaNeueCyr.woff') format('woff');
font-weight: normal;
font-style: normal;
}
module.exports = {
output: {
path: __dirname + '/web'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: ['babel-loader', 'eslint-loader']
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
options: { minimize: true }
}
]
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
{
test: /\.scss$/,
exclude: /node_modules/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts'
}
}]
},
{
test: /\.(jpg|png)$/,
use: {
loader: "file-loader",
options: {
name: 'images/[name].[ext]',
outputPath: 'images'
}
}
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: './src/index.html',
filename: './index.html'
}),
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css'
})
]
};