I have a problem compiling a project after saving a change in the files; the compilation time of the files takes 2 or more minutes.
To fix the problem, I took the following steps:
1.In babel-loader from the documentation in the option object for properties cacheDirectory set to true, cacheComprassion to false
2. In the ts-loader from the documentation in the option object for the properties transpileOnly and happyPackMode set to true
3.dev-tool disabled for better performance
4. ForkTsCheckerWebpackPlugin connected to check types in typescript
5. Code splitting customized
Webpack config file
const path = require('path');
const ESLintPlugin = require('eslint-webpack-plugin');
const webpack = require('webpack');
// eslint-disable-next-line import/no-extraneous-dependencies
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
entry: [
path.resolve(__dirname, 'src/index.tsx'),
],
mode: 'development',
module: {
rules: [
{ parser: { requireEnsure: false } },
{
test: /\.(ts|tsx)$/,
exclude: /(node_modules)/,
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: true,
cacheCompression: false,
},
},
{
loader: 'ts-loader', options: {
transpileOnly: true,
happyPackMode: true
},
},
],
},
{
test: /\.scss$/,
use: [
{
// creates style nodes from JS strings
loader: 'style-loader',
},
{
// translates CSS into CommonJS
loader: 'css-loader',
},
{
// compiles Sass to CSS
loader: 'sass-loader',
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: [
// eslint-disable-next-line global-require
require('autoprefixer'),
],
},
},
],
},
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'less-loader'],
}),
},
{
test: /\.css$/,
use: [
{
// creates style nodes from JS strings
loader: 'style-loader',
},
{
// translates CSS into CommonJS
loader: 'css-loader',
},
],
},
{
test: /\.svg/,
use: {
loader: 'svg-url-loader',
},
},
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
},
],
},
],
},
// devtool: 'source-map',
optimization: {
runtimeChunk: {
name: 'app',
},
splitChunks: {
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
minimize: true,
},
resolve: { extensions: ['*', '.js', '.jsx', '.ts', '.tsx', 'scss'], modules: ['node_modules'] },
output: {
// path: `${__dirname}/dist`,
// filename: 'app.js',
publicPath: 'http://localhost:3000/hmr/',
chunkFilename: '[id].js?v=[chunkhash]',
},
devServer: {
stats: {
// assets: true,
// cachedAssets: true,
// performance: true,
// entrypoints: true,
// chunkGroups: true,
// chunks: true,
// chunkModules: true,
// show modules contained in each chunk
// chunkOrigins: true,
// show the origin of a chunk (why was this chunk created)
// chunkRelations: true,
// show relations to other chunks (parents, children, sibilings)
// dependentModules: true,
},
disableHostCheck: true,
host: '127.0.0.1',
port: 3000,
publicPath: '/hmr/',
filename: 'app.js',
// hot: true,
// hotOnly: true,
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new ForkTsCheckerWebpackPlugin({
typescript: {
diagnosticOptions: {
semantic: true,
syntactic: true,
},
},
async: true,
}),
new ESLintPlugin({
eslintPath: 'eslint',
fix: true,
quiet: true,
extensions: ['ts', 'tsx'],
}),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
],
};
Please tell me how you can reduce the compilation time of files in the project after saving the files?
Solved the issue. The problem turned out to be in the eslint-loader-webpack plugin. If you install the old version of eslint-loader, then everything works fine.
How to solve the issue of the eslint-loader-webpack plugin slow?
Related
It's important to first say that everything was working, but it somehow just broke.
I am trying to get standalone css files and will include them in my index.html file
But the css is still loaded inline in main.bundle.js, but the css is missing from the page. I've noticed in main.bundle.js I see a lot of "\n"
padding-right: 15px;\n}\n.btn.content-btn::before {\n position: absolute;\n
I know this webpack file is messy but I have been trying different variations for hours.
I am new to wepback so I would appreciate some help. I am using webpack 5.68.0
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ESLintPlugin = require('eslint-webpack-plugin');
const Dotenv = require('dotenv-webpack');
// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// css twice [CONTENTS]
module.exports = {
mode: 'development',
//devtool: 'inline-module-source-map',
devtool: 'source-map',
entry: [
'./src/index.js'
],
output: {
// path: __dirname + '/dist',
path: __dirname + '/public',
publicPath: '/',
filename: '[name].bundle.js',
},
optimization: {
runtimeChunk: 'single',
splitChunks: {
chunks: 'async',
minSize: 60000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
cacheGroups: {
// styles: {
// name: 'styles',
// test: /\.s?css$/,
// chunks: 'all',
// minChunks: 1,
// reuseExistingChunk: true,
// enforce: true,
// },
vendor: {
test: /node_modules/,
name: 'vendor',
chunks: 'initial',
enforce: true
},
vendorModules: {
test: /src\/js\/modules/,
name: 'vendor-modules',
chunks: 'initial',
enforce: true
}
}
}
},
module: {
rules: [
{
enforce: 'pre',
test: /\.js$/,
exclude: /node_modules/,
// use: [
// 'babel-loader',
// 'eslint-loader',
// ]
use: [
{
loader: 'babel-loader',
},
// {
// loader: 'eslint-webpack-plugin',
// options: {
// quiet: true
// }
// }
]
},
{
test: /\.ts$/,
use: ['babel-loader']
},
{
test: /\.s[ac]ss$/i,
use: [
// Creates `style` nodes from JS strings
"style-loader",
// Translates CSS into CommonJS
"css-loader",
// Compiles Sass to CSS
"sass-loader",
// {
// loader: MiniCssExtractPlugin.loader,
// options: {
// publicPath: __dirname + '/public',
// },
// },
// {
// loader: 'css-loader',
// options: {
// importLoaders: 2,
// sourceMap: true
// }
// },
// {
// loader: "sass-loader",
// options: {
// sourceMap: true,
// sassOptions: {
// indentWidth: 2,
// includePaths: ["src/styles"],
// },
// },
// },
],
},
// {
// test: /\.s[ac]ss$/i,
// //test: /\.scss$/,
// //test: /\.s[ac]ss$/i,
// exclude: /node_modules/,
// use: [
// {
// loader: 'file-loader',
// options: { outputPath: 'css/', name: '[name].min.css'}
// },
// 'style-loader',
// {
// loader: "sass-loader"
// }
// ]
// },
// {
// test: /\.s[ac]ss$/i,
// use: [
// // something is making styles show up twice. I don't want style loader loads twice???
// "style-loader", // Creates `style` nodes from JS strings
// "css-loader", // Translates CSS into CommonJS
// {
// loader: 'sass-loader',
// options: {
// sourceMap: true
// }
// }, // Compiles Sass to CSS
// ],
// },
{
test: /\.svg$/,
loader: 'svg-inline-loader'
}
// {
// test: /\.svg$/,
// use: [
// {
// loader: 'svg-url-loader',
// options: {
// limit: 10000,
// },
// },
// ],
// },
]
},
resolve: {
extensions: ['.js', '.jsx', ".ts"],
fallback: {
"fs": false,
"os": false,
"tls": false,
"net": false,
"path": false,
"zlib": false,
"http": false,
"https": false,
"browser": false,
"stream": require.resolve("stream-browserify"),
"buffer": require.resolve("buffer"),
"crypto": false,
"crypto-browserify": require.resolve('crypto-browserify'), //if you want to use this module also don't forget npm i crypto-browserify
}
},
devServer: {
allowedHosts: [
'learntoearn.dev',
],
historyApiFallback: true,
static: {
directory: path.join(__dirname, 'public'),
},
compress: true,
port: 8080,
},
plugins: [
new MiniCssExtractPlugin( // split css into files
{
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "[name].css",
chunkFilename: "[id].css"
}
),
//new BundleAnalyzerPlugin(),
new ESLintPlugin(),
new Dotenv(),
new ESLintPlugin({
quiet: true,
}),
new webpack.ProvidePlugin({
process: 'process/browser',
}),
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
}),
new webpack.HotModuleReplacementPlugin(),
new HtmlWebpackPlugin({
template: __dirname + '/public/index.html',
// template: __dirname + '/src/index.html',
filename: 'index.html',
inject: false // BROKE AGAIN FOR SOME REASON, SO SETTING TO TRUE
//inject: 'body' // causing styles to be loaded twice!
})
]
};
I had several issues for anyone who has this problem.
Delete node modules.
Clear yarn/npm cache.
Install everything again.
in your wepback file include this
{
//test: /\.s[ac]ss$/i,
test: /\.(s(a|c)ss)$/,
use: [
// Creates `style` nodes from JS strings
MiniCssExtractPlugin.loader,
// Translates CSS into CommonJS
"css-loader",
// Compiles Sass to CSS
{
loader: "sass-loader",
options: {
sourceMap: true,
},
},
],
},
in plugins, all you need is this
plugins: [
new MiniCssExtractPlugin(), // split css into files
Webpack then created a main.css file and included it in index.html
I am trying to integrate Creative Tim's Material Kit Pro React frontend with the generator for the backend provided here
I generated a material ui react app using the back end yo generator. I then installed the additional dependencies specified in the Creative Tim file. At that point, I get an error. SCSS files that previously loaded in the original app now throw an error that says:
Uncaught Error: Cannot find module "./LoadingSpinner.scss"
at webpackMissingModule (LoadingSpinner.js:4)
I have copied both webpack.config.js files but they are so different, I can't get a grip on where to start integrating them.
Has anyone tried to use both packages?
Material Kit Pro React webpack.config.js has:
const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
if (process.env.NODE_ENV === 'test') {
require('dotenv').config({ path: '.env.test'});
} else if (process.env.NODE_ENV === 'development') {
require('dotenv').config({ path: '.env.development'});
}
module.exports = (env) => {
const isProduction = env ==='production';
const CSSExtract = new ExtractTextPlugin('styles.css');
return {
entry: './src/index.js',
output: {
path: path.join(__dirname, 'public', 'dist'),
filename: 'bundle.js'
},
// resolve: { alias: { Assets: path.resolve(__dirname, 'src/assets') } },
module: {
rules: [{
loader: 'babel-loader',
test: /\.js$/,
exclude: /node_modules/
}, {
test: /\.s?css$/,
use: CSSExtract.extract({
use: [
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
})
}]
},
plugins: [
CSSExtract,
new webpack.DefinePlugin({
'process.env.REACT_APP_FIREBASE_API_KEY': JSON.stringify(process.env.REACT_APP_FIREBASE_API_KEY),
'process.env.REACT_APP_FIREBASE_AUTH_DOMAIN': JSON.stringify(process.env.REACT_APP_FIREBASE_AUTH_DOMAIN),
'process.env.REACT_APP_FIREBASE_DATABASE_URL': JSON.stringify(process.env.REACT_APP_FIREBASE_DATABASE_URL),
'process.env.REACT_APP_FIREBASE_PROJECT_ID': JSON.stringify(process.env.REACT_APP_FIREBASE_PROJECT_ID),
'process.env.REACT_APP_FIREBASE_STORAGE_BUCKET': JSON.stringify(process.env.REACT_APP_FIREBASE_STORAGE_BUCKET),
'process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID': JSON.stringify(process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID)
})
],
devtool: isProduction ? 'source-map' : 'inline-source-map',
devServer: {
contentBase: path.join(__dirname, 'public'),
historyApiFallback: true,
publicPath: '/dist/'
}
};
};
Backend generator has:
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const project = require('../project.config')
const inProject = path.resolve.bind(path, project.basePath)
const inProjectSrc = file => inProject(project.srcDir, file)
const __DEV__ = project.env === 'development'
const __TEST__ = project.env === 'test'
const __PROD__ = project.env === 'production'
const config = {
entry: {
normalize: [inProjectSrc('normalize')],
main: [inProjectSrc(project.main)]
},
devtool: project.sourcemaps ? 'source-map' : false,
output: {
path: inProject(project.outDir),
filename: __DEV__ ? '[name].js' : '[name].[chunkhash].js',
publicPath: project.publicPath
},
resolve: {
modules: [inProject(project.srcDir), 'node_modules'],
extensions: ['*', '.js', '.jsx', '.json']
},
externals: project.externals,
module: {
rules: []
},
plugins: [
new webpack.DefinePlugin(
Object.assign(
{
'process.env': { NODE_ENV: JSON.stringify(project.env) },
__DEV__,
__TEST__,
__PROD__
},
project.globals
)
)
],
node: {
// disable node constants so constants.js file is used instead (see https://webpack.js.org/configuration/node/)
constants: false
}
}
// JavaScript
// ------------------------------------
config.module.rules.push({
test: /\.(js|jsx)$/,
exclude: [
/node_modules/,
/redux-firestore\/es/,
/react-redux-firebase\/es/
// Add other packages that you are npm linking here
],
use: [
{
loader: 'babel-loader',
query: {
cacheDirectory: true,
// ignore root .babelrc (Check issue #59 for more details)
babelrc: false,
plugins: [
'lodash',
'transform-decorators-legacy',
'babel-plugin-transform-class-properties',
'babel-plugin-syntax-dynamic-import',
'babel-plugin-transform-export-extensions',
[
'babel-plugin-transform-runtime',
{
helpers: true,
polyfill: false, // we polyfill needed features in src/normalize.js
regenerator: true
}
],
[
'babel-plugin-transform-object-rest-spread',
{
useBuiltIns: true // we polyfill Object.assign in src/normalize.js
}
]
],
presets: [
'babel-preset-react',
[
'babel-preset-env',
{
targets: {
ie9: true,
uglify: true,
modules: false
}
}
]
]
}
}
]
})
// Styles
// ------------------------------------
const extractStyles = new ExtractTextPlugin({
filename: 'styles/[name].[contenthash].css',
allChunks: true,
disable: __DEV__
})
config.module.rules.push({
test: /\.(sass|scss)$/,
loader: extractStyles.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
sourceMap: project.sourcemaps,
modules: true,
importLoaders: 2,
localIdentName: '[name]__[local]___[hash:base64:5]',
minimize: {
autoprefixer: {
add: true,
remove: true,
browsers: ['last 2 versions']
},
discardComments: {
removeAll: true
},
discardUnused: false,
mergeIdents: false,
reduceIdents: false,
safe: true,
sourcemap: project.sourcemaps
}
}
},
{
loader: 'sass-loader',
options: {
sourceMap: project.sourcemaps,
includePaths: [inProjectSrc('styles')]
}
}
]
})
})
config.plugins.push(extractStyles)
// Images
// ------------------------------------
config.module.rules.push({
test: /\.(png|jpg|gif)$/,
loader: 'url-loader',
options: {
limit: 8192
}
})
// Fonts
// ------------------------------------
;[
['woff', 'application/font-woff'],
['woff2', 'application/font-woff2'],
['otf', 'font/opentype'],
['ttf', 'application/octet-stream'],
['eot', 'application/vnd.ms-fontobject'],
['svg', 'image/svg+xml']
].forEach(font => {
const extension = font[0]
const mimetype = font[1]
config.module.rules.push({
test: new RegExp(`\\.${extension}$`),
loader: 'url-loader',
options: {
name: 'fonts/[name].[ext]',
limit: 10000,
mimetype
}
})
})
// HTML Template
// ------------------------------------
config.plugins.push(
new HtmlWebpackPlugin({
template: inProjectSrc('index.html'),
inject: true,
minify: {
collapseWhitespace: true
}
})
)
// Development Tools
// ------------------------------------
if (__DEV__) {
config.entry.main.push(
`webpack-hot-middleware/client.js?path=${
config.output.publicPath
}__webpack_hmr`
)
config.plugins.push(
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin()
)
}
// Bundle Splitting
// ------------------------------------
if (!__TEST__) {
const bundles = ['normalize', 'manifest']
if (project.vendors && project.vendors.length) {
bundles.unshift('vendor')
config.entry.vendor = project.vendors
}
config.plugins.push(
new webpack.optimize.CommonsChunkPlugin({ names: bundles })
)
}
// Production Optimizations
// ------------------------------------
if (__PROD__) {
config.plugins.push(
new webpack.LoaderOptionsPlugin({
minimize: true,
debug: false
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: !!config.devtool,
comments: false,
compress: {
warnings: false,
screw_ie8: true,
conditionals: true,
unused: true,
comparisons: true,
sequences: true,
dead_code: true,
evaluate: true,
if_return: true,
join_vars: true
}
})
)
}
module.exports = config
I can see the css loaders are different, but I can't see what to do to make the Creative Tim files work with this backend. Has anyone figured this out?
I have tried adding tests to the module exports statement in the generator so that it reads as follows:
module: {
rules: [{
test: /\.scss$/,
use: [{
loader: "style-loader"
}, {
loader: "css-loader"
}, {
loader: "sass-loader",
// options: {
// includePaths: ["absolute/path/a", "absolute/path/b"]
// }
}],
}],
},
That attempt produces a new error that reads:
web.dom.iterable.js:19 Uncaught Error: Module build failed:
#import 'base';
^
Invalid CSS after "": expected 1 selector or at-rule, was "var content = requi"
I also tried adding style-loader as an additional loader to the webpack.config file (alongside css-loader and sass-loader), but that produces the following error:
Invalid CSS after "": expected 1 selector or at-rule, was "var content = requi"
(line 1, column 1)
at Object../node_modules/css-loader/index.js!./node_modules/sass-loader/lib/loader.js!./node_modules/extract-text-webpack-plugin/dist/loader.js??ref--2-0!./node_modules/style-loader/index.js!./node_modules/css-loader/index.js??ref--2-2!./node_modules/sass-loader/lib/loader.js??ref--2-
Others who have had problems getting the css configured suggest that there may be config defined elsewhere. I don't seem to have that. I am about halfway through deleting all the references to css in the backend generated file. That was working (up to newProjectTile) but now that still generates failure to build css error.
Driving me crazy that config is so complicated across these tools. If anyone has added a custom theme to the backend generator (regardless of whether it's the Creative Tim theme or otherwise), have you found a way to compile CSS? Any tips would be very much appreciated.
Currently, my webpack.config file is as follows - errors galore in the console and still no closer to an idea for how to resolve them.
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const project = require('../project.config')
const inProject = path.resolve.bind(path, project.basePath)
const inProjectSrc = file => inProject(project.srcDir, file)
const __DEV__ = project.env === 'development'
const __TEST__ = project.env === 'test'
const __PROD__ = project.env === 'production'
const CSSExtract = new ExtractTextPlugin('styles.css');
const config = {
entry: {
normalize: [inProjectSrc('normalize')],
main: [inProjectSrc(project.main)]
},
devtool: project.sourcemaps ? 'source-map' : false,
output: {
path: inProject(project.outDir),
filename: __DEV__ ? '[name].js' : '[name].[chunkhash].js',
publicPath: project.publicPath
},
resolve: {
modules: [inProject(project.srcDir), 'node_modules'],
extensions: ['*', '.js', '.jsx', '.json']
},
externals: project.externals,
module: {
rules: [{
loader: 'babel-loader',
test: /\.js$/,
exclude: /node_modules/
}, {
test: /\.s?css$/,
use: CSSExtract.extract({
use: [
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'style-loader',
options: {
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
})
}]
},
plugins: [
CSSExtract,
new webpack.DefinePlugin(
Object.assign(
{
'process.env': { NODE_ENV: JSON.stringify(project.env) },
__DEV__,
__TEST__,
__PROD__
},
project.globals
)
)
],
node: {
// disable node constants so constants.js file is used instead (see https://webpack.js.org/configuration/node/)
constants: false
}
}
// JavaScript
// ------------------------------------
config.module.rules.push({
test: /\.(js|jsx)$/,
exclude: [
/node_modules/,
/redux-firestore\/es/,
/react-redux-firebase\/es/
// Add other packages that you are npm linking here
],
use: [
{
loader: 'babel-loader',
query: {
cacheDirectory: true,
// ignore root .babelrc (Check issue #59 for more details)
babelrc: false,
plugins: [
'lodash',
'transform-decorators-legacy',
'babel-plugin-transform-class-properties',
'babel-plugin-syntax-dynamic-import',
'babel-plugin-transform-export-extensions',
[
'babel-plugin-transform-runtime',
{
helpers: true,
polyfill: false, // we polyfill needed features in src/normalize.js
regenerator: true
}
],
[
'babel-plugin-transform-object-rest-spread',
{
useBuiltIns: true // we polyfill Object.assign in src/normalize.js
}
]
],
presets: [
'babel-preset-react',
[
'babel-preset-env',
{
targets: {
ie9: true,
uglify: true,
modules: false
}
}
]
]
}
}
]
})
// Styles
// ------------------------------------
const extractStyles = new ExtractTextPlugin({
filename: 'styles/[name].[contenthash].css',
allChunks: true,
disable: __DEV__
})
config.module.rules.push({
test: /\.(sass|scss)$/,
loader: extractStyles.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
sourceMap: project.sourcemaps,
modules: true,
importLoaders: 2,
localIdentName: '[name]__[local]___[hash:base64:5]',
minimize: {
autoprefixer: {
add: true,
remove: true,
browsers: ['last 2 versions']
},
discardComments: {
removeAll: true
},
discardUnused: false,
mergeIdents: false,
reduceIdents: false,
safe: true,
sourcemap: project.sourcemaps
}
}
},
{
loader: 'style-loader'
},
{
loader: 'sass-loader',
options: {
sourceMap: project.sourcemaps,
includePaths: [inProjectSrc('styles')]
}
}
]
})
})
config.plugins.push(extractStyles)
// Images
// ------------------------------------
config.module.rules.push({
test: /\.(png|jpg|gif)$/,
loader: 'url-loader',
options: {
limit: 8192
}
})
// Fonts
// ------------------------------------
;[
['woff', 'application/font-woff'],
['woff2', 'application/font-woff2'],
['otf', 'font/opentype'],
['ttf', 'application/octet-stream'],
['eot', 'application/vnd.ms-fontobject'],
['svg', 'image/svg+xml']
].forEach(font => {
const extension = font[0]
const mimetype = font[1]
config.module.rules.push({
test: new RegExp(`\\.${extension}$`),
loader: 'url-loader',
options: {
name: 'fonts/[name].[ext]',
limit: 10000,
mimetype
}
})
})
// HTML Template
// ------------------------------------
config.plugins.push(
new HtmlWebpackPlugin({
template: inProjectSrc('index.html'),
inject: true,
minify: {
collapseWhitespace: true
}
})
)
// Development Tools
// ------------------------------------
if (__DEV__) {
config.entry.main.push(
`webpack-hot-middleware/client.js?path=${
config.output.publicPath
}__webpack_hmr`
)
config.plugins.push(
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin()
)
}
// Bundle Splitting
// ------------------------------------
if (!__TEST__) {
const bundles = ['normalize', 'manifest']
if (project.vendors && project.vendors.length) {
bundles.unshift('vendor')
config.entry.vendor = project.vendors
}
config.plugins.push(
new webpack.optimize.CommonsChunkPlugin({ names: bundles })
)
}
// Production Optimizations
// ------------------------------------
if (__PROD__) {
config.plugins.push(
new webpack.LoaderOptionsPlugin({
minimize: true,
debug: false
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: !!config.devtool,
comments: false,
compress: {
warnings: false,
screw_ie8: true,
conditionals: true,
unused: true,
comparisons: true,
sequences: true,
dead_code: true,
evaluate: true,
if_return: true,
join_vars: true
}
})
)
}
module.exports = config
i am having troubles setting up webpack build configuration.
i have two webpack config files, one for development and one for production.
everything works fine in dev environment, but when building for production, i get this error:
ReferenceError: _ref2 is not defined
at e.value (App.js:20)
at c (react-dom.production.min.js:147)
at beginWork (react-dom.production.min.js:150)
at i (react-dom.production.min.js:182)
at c (react-dom.production.min.js:183)
at l (react-dom.production.min.js:184)
at v (react-dom.production.min.js:188)
at h (react-dom.production.min.js:187)
at Object.updateContainer (react-dom.production.min.js:248)
at react-dom.production.min.js:254
so this is my webpack config files:
webpack.config.dev.js
import webpack from 'webpack';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import path from 'path';
// import 'babel-polyfill';
export default {
resolve: {
extensions: ['*', '.js', '.jsx', '.json']
},
devtool: 'cheap-module-eval-source-map', // more info:https://webpack.js.org/guides/development/#using-source-maps and https://webpack.js.org/configuration/devtool/
entry: [
// must be first entry to properly set public path
'babel-polyfill',
'./src/webpack-public-path',
'react-hot-loader/patch',
'webpack-hot-middleware/client?reload=true',
path.resolve(__dirname, 'src/index.js') // Defining path seems necessary for this to work consistently on Windows machines.
],
target: 'web',
output: {
path: path.resolve(__dirname, 'dist'), // Note: Physical files are only output by the production build task `npm run build`.
publicPath: '/',
filename: 'bundle.js'
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development'), // Tells React to build in either dev or prod modes. https://facebook.github.io/react/downloads.html (See bottom)
__DEV__: true
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new HtmlWebpackPlugin({ // Create HTML file that includes references to bundled CSS and JS.
template: 'src/index.ejs',
minify: {
removeComments: true,
collapseWhitespace: true
},
inject: true
})
],
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: ['babel-loader']
},
{
test: /\.eot(\?v=\d+.\d+.\d+)?$/,
use: ['file-loader']
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff'
}
}
]
},
{
test: /\.[ot]tf(\?v=\d+.\d+.\d+)?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/octet-stream'
}
}
]
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'image/svg+xml'
}
}
]
},
{
test: /\.(jpe?g|png|gif|ico)$/i,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]'
}
}
]
},
{
test: /(\.css|\.scss|\.sass)$/,
exclude: /node_modules/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
sourceMap: true
}
}, {
loader: 'postcss-loader',
options: {
plugins: () => [
require('autoprefixer')
],
sourceMap: true
}
}, {
loader: 'sass-loader',
options: {
includePaths: [path.resolve(__dirname, 'src', 'scss')],
sourceMap: true
}
}
]
}
]
}
};
webpack.config.prod.js
// For info about this file refer to webpack and webpack-hot-middleware documentation
// For info on how we're generating bundles with hashed filenames for cache busting: https://medium.com/#okonetchnikov/long-term-caching-of-static-assets-with-webpack-1ecb139adb95#.w99i89nsz
import webpack from 'webpack';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import WebpackMd5Hash from 'webpack-md5-hash';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import path from 'path';
const GLOBALS = {
'process.env.NODE_ENV': JSON.stringify('production'),
__DEV__: false
};
export default {
resolve: {
extensions: ['*', '.js', '.jsx', '.json']
},
devtool: 'source-map', // more info:https://webpack.js.org/guides/production/#source-mapping and https://webpack.js.org/configuration/devtool/
entry: ['babel-polyfill', './src/webpack-public-path', path.resolve(__dirname, 'src/index.js')],
target: 'web',
output: {
path: path.resolve(__dirname, 'dist'),
publicPath: '',
filename: '[name].[chunkhash].js'
},
plugins: [
// Hash the files using MD5 so that their names change when the content changes.
new WebpackMd5Hash(),
// Tells React to build in prod mode. https://facebook.github.io/react/downloads.html
new webpack.DefinePlugin(GLOBALS),
// Generate an external css file with a hash in the filename
new ExtractTextPlugin('[name].[contenthash].css'),
// Generate HTML file that contains references to generated bundles. See here for how this works: https://github.com/ampedandwired/html-webpack-plugin#basic-usage
new HtmlWebpackPlugin({
template: 'src/index.ejs',
favicon: 'src/favicon.ico',
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true
},
inject: true
}),
// Minify JS
new webpack.optimize.UglifyJsPlugin({sourceMap: true}),
],
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: ['babel-loader']
},
{
test: /\.eot(\?v=\d+.\d+.\d+)?$/,
use: [
{
loader: 'url-loader',
options: {
name: 'fonts/[name].[contenthash].[ext]'
}
}
]
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff',
name: 'fonts/[name].[contenthash].[ext]'
}
}
]
},
{
test: /\.[ot]tf(\?v=\d+.\d+.\d+)?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/octet-stream',
name: 'fonts/[name].[contenthash].[ext]'
}
}
]
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'image/svg+xml',
name: 'img/[name].[contenthash].[ext]'
}
}
]
},
{
test: /\.(jpe?g|png|gif)$/i,
use: [
{
loader: 'file-loader',
options: {
name: 'img/[name].[contenthash].[ext]'
}
}
]
},
{
test: /(\.css|\.scss|\.sass)$/,
exclude: /node_modules/,
use: ExtractTextPlugin.extract({
use: [
{
loader: 'css-loader',
options: {
minimize: true,
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
plugins: () => [
require('autoprefixer')
],
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
includePaths: [path.resolve(__dirname, 'src', 'scss')],
sourceMap: true
}
}
]
})
}
]
}
};
.babelrc
{
"presets": [
"react",
"stage-1",
"flow"
],
"env": {
"development": {
"presets": [
"env",
"react-hmre"
],
"plugins": [
"transform-regenerator",
[
"transform-class-properties",
{
"spec": true
}
]
]
},
"production": {
"presets": [
[
"env",
{
"es2015": {
"modules": false
},
"targets": {
"ie": 9,
"uglify": true
}
}
]
],
"plugins": [
"transform-regenerator",
"transform-react-constant-elements",
"transform-react-remove-prop-types",
[
"transform-class-properties",
{
"spec": true
}
]
]
},
"test": {
"presets": [
"env"
],
"plugins": [
"transform-regenerator",
[
"transform-class-properties",
{
"spec": true
}
]
]
}
}
}
i have no idea which configuration may be causing this erros.
I think this is not a webpack issue, it's App.js file.
In my case, there was a 'let' declaration issue. It was working in a dev environment but wasn't on a production build. Basically, in the build process, we need to take special care of const/let/function declarations order and scope, so that after the build, declaration reference will get actual declarations.
My case was:
const products = products.map(group => {
let resultButton = '';
if (!group.product[0].soldout) {
let price = 0;
price += group.product[0].amount.amount;
if (group.product[0].fees) {
for (let i = 0; i < group.product[0].fees.length; i += 1) {
price += group.product[0].fees[i].amount;
}
}
// here was my wrong declaration
// I corrected by declaring outside of if (!group.product[0].soldout)
// below let resultButton = '';
// & it works for me after build
let benefits = <li>No benefits defined</li>;
if (
group.product[0].properties&&
group.product[0].properties.length > 0
) {
_.map(group.product[0].properties.property, property => {
if (property.code === 51) {
const benefitsArray = property.content.split('\n');
benefits = benefitsArray.map(item => {
const st = item.replace(/ +/g, '');
return <li key={st}>{item}</li>;
});
}
});
}
resultButton = (
<div>
<h4>
<ul>{benefits}</ul>
</div>
);
} else {
resultButton = (
<div>
<SoldOut>
</div>
);
}
return resultButton;
});
Hope you'll get the answer.
I am coding some learning project to implement TDD, webpack.
I use webpack 2 with the following config:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
//const ExtractTextPlugin = require('extract-text-webpack-plugin');
const WebpackMd5Hash = require('webpack-md5-hash');
process.noDeprecation = true;
module.exports = {
entry: './src/js/index.js',
devtool: 'source-map',
context: __dirname,
target: 'web',
stats: 'errors-only',
watch: true,
output: {
path: path.resolve(__dirname, './dist'),
filename: 'js/[name].[chunkHash].js',
publicPath: '/',
},
module: {
rules: [
{
test: /\.jsx?$/,
include: [
path.resolve(__dirname, 'src')
],
exclude: [
path.resolve(__dirname, 'node_modules')
],
loader: 'babel-loader',
options: {
presets: ['es2015']
},
},
{
test: /\.css$/,
/*use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})*/
use: [ 'style-loader', 'css-loader' ]
}
]
},
plugins: [
new WebpackMd5Hash(),
//new ExtractTextPlugin('[name].[contenthash].css'),
new HtmlWebpackPlugin({
template: 'src/index.html',
filename: 'index.html',
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true
},
inject: true
}),
new webpack.optimize.UglifyJsPlugin()
],
devServer: {
contentBase: path.join(__dirname, "dist/"),
compress: true,
port: 8080
}
}
When I run simply webpack it compiles and works fine. But when I try to run karma with webpack preprocessor, it gives the following error:
Uncaught Error: Module parse failed: C:\Users\Javid\Desktop\projects\rejection\src\css\style.css Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
I use import '../css/style.css'; in my js file. Googled it a lot, didn't find a solution.
Solution
I used additionaly raw-loader to handle my css and changed my import to look like this: import css from 'raw-loader!../css/style.css';
Reference: https://angular.io/docs/ts/latest/guide/webpack.html
This site shows a good example of a project for development, test, and production builds. In particular to your question, it looks as if a loader is used to ignore the .css files when running karma.
Here is a sample of their files related to karma:
"karma.config.js":
module.exports = require('./config/karma.conf.js');
"karma.conf.js":
var webpackConfig = require('./webpack.test');
module.exports = function (config) {
var _config = {
basePath: '',
frameworks: ['jasmine'],
files: [
{pattern: './config/karma-test-shim.js', watched: false}
],
preprocessors: {
'./config/karma-test-shim.js': ['webpack', 'sourcemap']
},
webpack: webpackConfig,
webpackMiddleware: {
stats: 'errors-only'
},
webpackServer: {
noInfo: true
},
reporters: ['kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['Chrome'],
singleRun: true
};
config.set(_config);
};
"webpack.test.js":
var webpack = require('webpack');
var helpers = require('./helpers');
module.exports = {
devtool: 'inline-source-map',
resolve: {
extensions: ['.ts', '.js']
},
module: {
rules: [
{
test: /\.ts$/,
loaders: [
{
loader: 'awesome-typescript-loader',
options: { configFileName: helpers.root('src', 'tsconfig.json') }
} , 'angular2-template-loader'
]
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'null-loader'
},
{
test: /\.css$/,
exclude: helpers.root('src', 'app'),
loader: 'null-loader'
},
{
test: /\.css$/,
include: helpers.root('src', 'app'),
loader: 'raw-loader'
}
]
},
plugins: [
new webpack.ContextReplacementPlugin(
// The (\\|\/) piece accounts for path separators in *nix and Windows
/angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
helpers.root('./src'), // location of your src
{} // a map of your routes
)
]
}
I'm trying to figure out why my vendor and manifest files are minified and uglified but my bundle is not. Could it be the order of the plugins? Maybe something to do with the CommonsChunkPlugin?
This is my UglifyJsPlugin code:
new webpack.optimize.UglifyJsPlugin({
debug: false,
minimize: true,
sourceMap: false,
output: {
comments: false
},
compressor: { // eslint-disable-line camelcase
warnings: false,
unused: true,
dead_code: true
},
mangle: false
}),
and this is my webpack config object a whole:
const webpack = require('webpack');
const conf = require('./gulp.conf');
const path = require('path');
const del = require('del');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const pkg = require('../package.json');
const autoprefixer = require('autoprefixer');
module.exports = {
entry: {
bundle: `./${conf.path.src('index')}`,
vendor: `./src/app/dependencies`,
},
output: {
path: path.join(process.cwd(), conf.paths.dist),
filename: '[name].[chunkhash].js'
},
module: {
rules: [
{
test: /.json$/,
use: ['json-loader']
},
{
test: /.ts$/,
exclude: /node_modules/,
enforce: 'pre',
use: ['tslint-loader']
},
{
test: /\.(css|scss)$/,
use: [
'style-loader',
'css-loader',
'sass-loader',
'postcss-loader'
]
},
{
test: /\.js$/,
exclude: /node_modules/,
use: [
'ng-annotate-loader',
'babel-loader'
]
},
{
test: /\.ts$/,
exclude: /node_modules/,
use: ['ts-loader']
},
{
test: /.html$/,
use: ['html-loader']
},
{
test: /\.(jade|pug)$/,
use: ['pug-html-loader']
},
{
test: /\.(eot|woff|woff2|ttf|svg|png|jpg)$/,
use: ['url-loader?limit=30000&name=[name]-[hash].[ext]']
},
{
test: /\.less$/,
use: ['style-loader','css-loader', 'less-loader']
}
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin({
debug: false,
minimize: true,
sourceMap: false,
output: {
comments: false
},
compressor: { // eslint-disable-line camelcase
warnings: false,
unused: true,
dead_code: true
},
mangle: false
}),
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', 'manifest']
}),
new webpack.optimize.OccurrenceOrderPlugin(),
// new webpack.NoErrorsPlugin(), // emits no scripts to browser if there are any errors at all
new HtmlWebpackPlugin({
template: conf.path.src('index.html'),
inject: true
}),
new webpack.ContextReplacementPlugin(
/angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
conf.paths.src
),
new webpack.DefinePlugin({
'process.env.NODE_ENV': '"production"'
}),
new ExtractTextPlugin('index-[contenthash].css'),
new webpack.LoaderOptionsPlugin({
options: {
postcss: () => [autoprefixer],
resolve: {},
ts: {
configFileName: 'tsconfig.json'
},
tslint: {
configuration: require('../tslint.json')
}
}
}),
new CopyWebpackPlugin([{
from: path.join(conf.paths.src, 'integration', 'embedder', 'embedder.js'),
to: path.join('integration', 'embedder', 'embedder.js')
}])
],
resolve: {
extensions: [
'.webpack.js',
'.web.js',
'.js',
'.ts'
]
}
};
turns out the answer was to add an options config to the babel-loader to include presets es2015 as so:
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'ng-annotate-loader'
},
{
loader: 'babel-loader',
options: {
presets: ['es2015'],
}
}
]
},
This is needed for uglify/minifying es6 code with webpack 2.