start
Preface: Webpack has been in use since entering the line until now, during which I have learned some things intermittently. The article plans to record what I learned from it. Just recently, Webpack 5 has been updated
Version 5.65.0 is used for this article
Initialize the project
1. Create folder, initialize NPM and install Webpack
NPM init // Enter all the way to NPM I webpack webpack-cli -dCopy the code
2. Create the project entry file SRC /index.js with a console
console.log('hello')
Copy the code
Initial Configuration
1. Create webPack configuration file, set entry and Output
We create webpack.config.js directly in the current directory
const path = require('path') module.exports = { entry: { index: path.resolve(__dirname, 'src/index.js') }, output: Resolve (__dirname, 'dist'), filename: '[name].js', clean: true // Clear directory before each packing}}Copy the code
In older versions, clean uses the clean-webpack-plugin
2, Add build command, add build command to script in package.json
"scripts": {
"build": "webpack --config webpack.config.js"
},
Copy the code
3. Run NPM run build, and if nothing goes wrong, it will generate dist/index.js, which is all we need to reference
html-webpack-plugin
We could write an index. HTML file in the dist directory by hand, but with clean enabled, it would not be appropriate to write every package by hand. In this case, we could use a plugin to solve the HTML-webpack-plugin
1. Install htML-webpack-plugin
npm i html-webpack-plugin -D
Copy the code
2. Add plugins to package.json
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, './index.html'),
filename: 'index.html'
})
]
Copy the code
3. Run NPM run build again
We can see that after build the dist directory came with index.html, and the HTML automatically introduced index.js. We even kindly added defer, which you can add if you don’t want to for compatibility
scriptLoading: 'blocking'
Copy the code
More configuration
Development mode
Now we can do very simple packaging, but there is still a lot of work to do, for example, every time we change the file, we need to repackage the code to see the effect, which is very unfriendly to development, so we need a development mode, there are two common ones, Watch and devServer
watch
This mode, as the name indicates, is automatically packaged to listen for file changes, and is easy to configure. We only need to add a command
"watch": "webpack --config webpack.config.js --watch"
Copy the code
Then we run NPM run watch to see that the current process did not terminate, tried to change index.js, repackaged, the contents of index.js also changed
devServer
This mode is to start a service locally that listens for changes, automatically refreshes, and so on
1. Install webpack-dev-server
npm i webpack-dev-server -D
Copy the code
2. Add configuration to webpack.config.js
DevServer: {port: 3000, // port open: true, // automatically open compress: true, // Enable gzip compression client: {progress: true // Browser printing progress}}Copy the code
Package. json add command
"dev": "webpack serve --config webpack.config.js"
Copy the code
After that we run NPM dev. After that the browser automatically opens localhost:3000 and changes to index.js will refresh automatically
Support the React
Now we need to add React support for our project
Install Babel
NPM i@babel /preset-env -d // NPM i@babel /preset-env -d // Escape JS syntax, promise, async, etc. NPM i@babel /preset-react -d // React syntax (JSX) NPM I babel-loader -d //loaderCopy the code
Configure the loader
1. Add webPack configuration, yes Babel handles our JS and JSX files
Module: {rules: [{test: / (\. JSX | \. Js) $/, use: [" Babel - loader "], exclude: excludes node_modules files/node_modules / / /}],}Copy the code
2. Add the Babel configuration, add the babel.config.js file under the project, and add the following configuration
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": 3
}
],
"@babel/preset-react"
]
}
Copy the code
Add. Browserslistrc file to configure browserslist
> 1%
last 2 versions
not ie <= 8
Copy the code
4. Test code
index.js
import {render} from 'react-dom'
import React from 'react'
import App from './App';
render(<App />, document.getElementById('root'))
Copy the code
App.js
import React from 'react'
const App = () => {
return <div>Hello React</div>
}
export default App
Copy the code
Then run NPM run dev and it will work
Handle exceptions
You might see a warning when it runs here
asset size limit: The following asset(s) exceed the recommended size limit (244 KiB). This can impact web performance.
Copy the code
This is because the size of a single file exceeds the size of the Webpack performance item configuration, which can be skipped in webPack plus the following configuration
performance: {
hints: false
},
Copy the code
With CSS
Working with CSS filescss-loader
style-loader
1. Install dependencies
NPM I CSs-loader -d // Processes the CSS file. NPM I style-loader -d // Inserts the CSS file with style after processingCopy the code
2. Add the configuration under rules
{
test: /\.css$/,
use:["style-loader","css-loader"],
exclude: /node_modules/
},
Copy the code
Now let’s import a CSS file and see that we have a style in our packaged page
Process SCSS filessass-loader
sass
1. Install dependencies
NPM I sass -d // core NPM I sass-loader -d // loaderCopy the code
2. Add the configuration under rules
{
test: /\.s(a|c)ss$/,
use:["style-loader","css-loader","sass-loader"],
exclude: /node_modules/
}
Copy the code
Separating CSS files
We now have a configuration that inserts CSS into JS, and then uses the style tag to insert the JS when it is executed. This significantly increases the package size of JS. In production environments, we usually separate CSS and JS files, which requires the use of a webpack plugin called mini-CSS-extract-plugin. We can still use style-loader in the development environment because it is faster than the mini-CSs-extract-plugin
1, install,
npm i mini-css-extract-plugin -D
Copy the code
2, use,
. const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const IS_DEV = process.env.NODE_ENV === 'development' ... {test: /\. CSS $/, use: [IS_DEV? "style-loader" : MiniCssExtractPlugin.loader, "css-loader"], exclude: /node_modules/ }, { test: /\.s(a|c)ss$/, use: [IS_DEV ? "style-loader" : MiniCssExtractPlugin.loader, "css-loader", "sass-loader"], exclude: /node_modules/} // Add new MiniCssExtractPlugin({filename: '[name].[hash].css' // Generate hash name}),Copy the code
CSSModule
You only need to enable modules in CSS-loader. The configuration is as follows
{
test: /\.s(a|c)ss$/,
use: [
IS_DEV ? "style-loader" : MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
modules: {
localIdentName: '[local]--[hash:base64:5]'
},
}
},
"sass-loader"
],
exclude: /node_modules/
}
Copy the code
usepostcss
Automatically adds the vendor prefix
Function: Auto each browser vendor prefix
1, install,
npm i postcss -D
npm i postcss-loader -D
npm i postcss-preset-env -D
Copy the code
2, configuration,
Add postCSS-loader to handle CSS location in Webpack after adding
{
test: /\.s(a|c)ss$/,
use: [
IS_DEV ? "style-loader" : MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
modules: {
localIdentName: '[local]--[hash:base64:5]'
},
sourceMap: IS_DEV
}
},
"postcss-loader",
"sass-loader"
],
exclude: /node_modules/
}
Copy the code
Then create a configuration file postcss.config.js in the root directory
module.exports = {
plugins: [
['postcss-preset-env']
]
}
Copy the code
Handle fileasset
replacefile-loader
和 url-loader
Before Webpack5, we deal with image resource files generally file-loader combined with URL-loader, small files base64 into JS, large files output files, Webpack5 directly has its own file processing function assetModule, configuration is relatively simple
{ test: /\.(png|svg|jpg|jpeg|gif)$/i, type: 'asset', parser: { dataUrlCondition: { maxSize: }}, Generator: {filename: 'static/[hash][ext][query]'}}Copy the code
To distinguish the environment
We usually have two environments in development, development environment and production environment. Webpack provides mode for us to distinguish configuration, while in packaging configuration, the same Loader may be configured differently for different environments, which makes us need two different configuration files
1. First we install the dependencies we need
NPM I webpack-merge -d // Merge configuration files NPM I cross-env -d // process.env is compatible with multiple environmentsCopy the code
2. Create a build directory for the package configuration and create the following file
webpack.development.js
Development Environment Configuration
Module. exports = {mode: 'development', performance: {hints: false}, devServer: {port: 1000, // port open: Client: {progress: true // Browser printing progress}}}Copy the code
webpack.production.js
Development Environment Configuration
module.exports = {
mode: "production"
}
Copy the code
webpack.common.js
Common configuration, used by both dev and PROd environments
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: { index: path.resolve(__dirname, '.. /src/index.js') }, output: { path: path.resolve(__dirname, '.. /dist'), filename: '[name].js', clean: true }, module: { rules: [ { test: /(\.jsx|\.js)$/, use: ["babel-loader"], exclude: /node_modules/ } ], }, plugins: [ new HtmlWebpackPlugin({ template: path.resolve(__dirname, '../index.html'), filename: 'index.html', scriptLoading: 'blocking' }) ] }Copy the code
webpack.config.js
Use different configurations depending on your environment
const merge = require('webpack-merge').default;
const commonConfig = require('./webpack.common');
const devConfig = require('./webpack.development');
const proConfig = require('./webpack.production');
module.exports = () => {
if(process.env.NODE_ENV === 'development') {
return merge(commonConfig, devConfig, {mode: 'development'})
}
return merge(commonConfig, proConfig, {mode: 'production'})
}
Copy the code
3. Modify the command
"build": "cross-env NODE_ENV=production webpack --config ./build/webpack.config.js",
"dev": "cross-env NODE_ENV=development webpack serve --config ./build/webpack.config.js"
Copy the code
Now we run NPM run dev during development, and run NPM run build package online
Why usecross-env
This is because different system commands vary when setting environment variables
- Windows
set NODE_ENV=development
Copy the code
- Max
export NODE_ENV=development
Copy the code
Cross-env helps us to be compatible with different systems
At the end
The React project has been developed and packaged with many optimizations, which will be written later