preface
Read a lot of webpack related articles, have been unable to read (or remember), nothing more than webpack official document configuration instructions, rearrange the order or translation is not good part of the re-processing. Rarely discuss how to build a Webpack project from 0 to 1 from a project perspective, and how to optimize step by step to achieve the best practice process with the increase of the complexity of the project after the completion of the construction.
This series is based on the webpack version below
"Webpack" : "^ 4.46.0", "webpack - dev - server" : "^ 3.11.2"Copy the code
[I] Project initialization
Create a new folder, webpack-demo, and run the following command.
npm init -y
npm install webpack webpack-cli -D
Copy the code
【 2 】 Configure packaged entry and output
Configure webpack.config.js with some code in the SRC /index.js directory
Module. exports = {entry:'./ SRC /index.js', // output: {path: Path.resolve (__dirname, "./dist"), // filename:"bundle.js"}}Copy the code
Configure the build command
1. Add build package commands to package.json scripts
scripts:{
"build": "webpack --config webpack.config.js"
}
Copy the code
2. Verify: NPM run build generates a bundle.js file in dist directory.
[4] Automatically import the bundle generated file bundle.js
- Install dependencies:
html-webpack-plugin
andclean-webpack-plugin
npm i -D html-webpack-plugin clean-webpack-plugin
Copy the code
- Configure webpack.config.js to be introduced as a plug-in
const HtmlWebpackPlugin = require("html-webpack-plugin"); const { CleanWebpackPlugin } = require("clean-webpack-plugin"); module.exports = { // ... Omit other plugins configuration project: [new CleanWebpackPlugin ({/ / empty packaging before every package output directory / / cleanOnceBeforeBuildPatterns: [' * * / * ', '! DLL, New HtmlWebpackPlugin({template: './index.html' // source template file // filename: './index.html' // Specify output file})]}Copy the code
Validation:
Terminal Execution commandnpm run build
The dist generator will be packaged in addition to bundle.js, as well as index.html. After this packaging, bundle.js is automatically injected intoindex.html
[V] Set up a local server
- Install dependencies
webpack-dev-server
npm i -D webpack-dev-server
Copy the code
2. Cooperate with service startup directory and port
module.exports = {
/ /... Omit other configuration items
devServer: {
port: 3001.hot: true.contentBase: "./dist",}}Copy the code
- Configure the local service startup command in package.json scripts
scripts:{
"serve": "webpack-dev-server --config webpack.config.js --open"
}
Copy the code
4. Verification: After NPM run serve is executed on the terminal, the browser will automatically open to start the local service
[vi] Configure the policy Module for parsing and converting files
Common loader
loder | function |
---|---|
babel-loader | Parse.js and.jsx files |
tsx-loader | Processing TS files |
less-loader | Process the LESS file and compile it into CSS |
sass-loader | Process SASS, SCSS files and compile them into CSS |
css-loader | Handles CSS files and returns an array of file names and CSS style content, usually used with style-loader |
style-loader | Inject CSS into the DOM(create a style from JS) |
file-loader | Parse the import/require on the file to a URL and print the file to the output directory |
url-loader | A Webpack loader for converting a file to a Base64 URI |
html-loader | Export the HTML as a string, minimizing the HTML when required by the compiler |
6.1 Processing JS (Introducing babel-Loader)
Since advanced syntax is not supported very well by different browsers, they are converted to ES5 standards for downward compatibility
- Install dependencies
babel-loader
(),@babel/core
和@babel/preset-env
npm install -D babel-loader @babel/core @babel/preset-env
Copy the code
- configuration
webpack.config.js
module.exports={
module:{
rules:[
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/ //
}
]
}
}
Copy the code
- New root directory. Babelrc
{"presets": ["@babel/preset-env" // Officially recommended, including all new features of modern JS (ES2015 ES2016 etc.)]}Copy the code
- If you wish to add lazy loading
npm i -D @babel/plugin-syntax-dynamic-import
Copy the code
Also update the.babelrc file to add the plugins configuration
{
"presets": [
"@babel/preset-env"]."plugins": [
"syntax-dynamic-import"]}Copy the code
Validation:
Add the arrow function to index.js and run the build command to view itbundle.js
Whether to convert ES6 arrow functions to normal functions
// Babel Input: ES2015 arrow function
[1, 2, 3].map((n) => n + 1);
// Babel Output: ES5 equivalent
[1, 2, 3].map(function(n) {
return n + 1;
});
Copy the code
6.2 Handling the CSS (SCSS LESS) this section uses SCSS as an example
- To support CSS imports, install dependencies
style-loader css-loader
npm i -D style-loader css-loader
Copy the code
- If we use sass to build the style, we need to install two more Node-sass sass-loaders
npm i -D node-sass sass-loader
Copy the code
3. Add a browser prefix to the CSS
npm i -D postcss-loader autoprefixer
Copy the code
3. Configure webpack.config.js, and let Webpack know which loader to load files with the corresponding suffix (.css and SCSS), so as to package them into bundle.js
module.exports = {
/ /... Omit other configuration items
module: {rules:[
{
test:/\.css$/,
use:['style-loader'.'css-loader'] // Parse principles from right to left
},
{
test:/\.scss$/,
use:['style-loader'.'css-loader'.'postcss-loader'.'sass-loader'] // Parse principles from right to left}}}]Copy the code
4. Verify: Create a.sccs file, write some SASS syntax styles, and cSS3 syntax, and see the actual output
// Variable definition
$color: blue;
body {
Nested / * * /
.test {
height: 100px;
display: flex;
align-items: center;
justify-content: center;
background-color: $color;
color: #fff; }}Copy the code
6.3 Processing multimedia files such as pictures and fonts
- To support import fonts, images, and other multimedia format files, install dependencies
url-loader file-loader
npm i -D url-loader file-loader
Copy the code
- Configure webpack.config.js to let Webpack know which loader to load these multimedia files
Note: Url-loader is generally used together with file-loader. The function is similar to file-loader, if the file size is smaller than the limit. Base64 encoding is returned, otherwise file-loader is used to move the file to the output directory
module.exports = { // ... {rules:{{test: /\.(jpe? G | PNG | GIF) $/ I / / picture file use: [{loader: 'url - loader, the options: {limit: 10240, fallback: {loader: 'file-loader', options: { name: 'img/[name].[hash:8].[ext]' } } } } ] }, { test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\? . *)? $/, // Media file use: [{loader: 'url-loader', options: {limit: 10240, fallback: {loader: 'file-loader', options: {name: 'media/[name].[hash:8].[ext]' } } } } ] }, { test: /\.(woff2? |eot|ttf|otf)(\? . *)? $/ I, // font use: [{loader: 'url-loader', options: {limit: 10240, fallback: {loader: 'file-loader', options: {name: 'fonts/[name].[hash:8].[ext]' } } } } ] }, ] } } }Copy the code
【 VII 】 Others
7.1 mode
The Mode configuration option notification is used to tell WebPack to use its built-in optimizations accordingly. The configuration options are Development, production, or None. For details, see the official documentation
7.2 devtool
Sourcemap is a mapping between generated code and source code that maps to source code. Once you understand the use of Source Maps, you can easily understand how to generate Source maps through Devtool’s configuration Webpack to enhance the debugging process. Different values significantly affect the speed of build and rebuild.
Production (mode=production)
: The default value is null. (None) or nosource-map is not setDevelopment environment (mode=development)
: The default value is eval. The common values are eval, cheap-eval-source-map, and cheap-module-eval-source-map
Sourcemap generates several policies:
value | The principle of | The advantages and disadvantages |
---|---|---|
eval | Wrap each module module in eval, which is not generated after compilationsourcemap File, simply add the sourceURL after each module to associate the relationship before and after the module processing |
The advantage is that packaging is very fast, since there is no need to generate sourcemap files. Disadvantages: The line count is not displayed correctly because it is mapped to the converted code, not to the original code. |
source-map | Generate a separate Sourcemap file for each packaged module, with the last line of packaged code being// #sourceMappingURL=bundle.js.map In the dist directory, a.map file is generated for each module |
Have complete source code information, easy to debug, but affect continuous build |
inline | Instead of generating a separate.map file, the.map The file is inserted as a dataURL |
Disadvantages: Larger packaged output files |
cheap | It is also generated for each file module when packaged.map File, but withsource-map The difference betweencheap-source-map The generated map file ignores the column information in the original code |
Can be substantially improvedsouremap The efficiency of the generation, but no column information (which is mapped to the transformed code, not to the original code), and usually we don’t care about column information when debugging |
module | A sourcemap file with no column information is also generated, and the Loader sourcemap is simplified to contain only the corresponding rows | supportbabel This precompilation tool finds the original source information |
How do I select the appropriate sourceMap generation strategy for different environments?
-
- The column information in the source code is of no use, so our packaged file does not want to contain column-related information, only the row information establishes the dependencies before and after the package. So whether it’s a development environment or a production environment, we want to add
cheap
To ignore column information before and after packaging.
- The column information in the source code is of no use, so our packaged file does not want to contain column-related information, only the row information establishes the dependencies before and after the package. So whether it’s a development environment or a production environment, we want to add
-
- In both development and formal environments, we want to locate the source code of the bug. For example, a vUE file reported an error. We want to locate the vUE file, so we also need the Module configuration.
-
- We need to generate the map file form, so we need to add
source-map
Properties.
- We need to generate the map file form, so we need to add
-
- When we introduced the EVAL packaging code, we learned that eval packaging is very fast because it does not generate map files, but can be used in combination with Eval
eval-source-map
The map file will be stored as a DataURL in a packaged JS file
- When we introduced the EVAL packaging code, we learned that eval packaging is very fast because it does not generate map files, but can be used in combination with Eval
It is therefore recommended that:
Module. exports = {devtool: // Eval is used to speed up packaging efficiency in development environments. Module. exports = {devtool: 'cheap-module-source-map'; // In the formal environment we can use module.exports = {devtool: 'cheap-module-source-map'; }Copy the code