Webpack was born for packaging.

A, preparation,

Learning webPack requires nodeJS to be installed first, and the authors emphasize that the new version of NodeJS will speed up webPack packaging. Once Node is installed, you can execute the following code from the project command line

npm init
Copy the code

If you want to set it, you can always press Enter, or you can use the default Settings

npm init -y
Copy the code

This allows you to generate package.json files in your project. The purpose of this is to make the project conform to the Node specification.


Install webPack

You can install webPack in either of the following ways: 1. Install WebPack globally (not recommended)

npm install webpack webpack-cli -g
Copy the code

After the installation is successful, you can run the webpack -v command to check whether the installation is successful. However, it is not recommended to install Webpack globally, because if there are multiple projects on the machine using different versions of Webpack, they cannot be compatible. Uninstall WebPack globally

npm uninstall webpack webpack-cli -g 
Copy the code

2. Install the Webpack (== Recommended ==) command line Access the project directory and run the following command

npm install webpack webpack-cli -D
Copy the code

-d = –dev (production)

The package.json package name is registered in devDependencies of package.json and only exists in the development environment. If you do not add -d to the package name, other developers will not know that you installed the package. -s: save the package name is registered in package.json dependencies.

Webpack -v cannot be used to view the webpack version after the installation is successful, because the default Node will look for webpacks globally. This is the case with the NPX command.

npx webpack -v
Copy the code

The NPX command will find our installed Webpack in node_modules of the current project

3. Install the customized WebPack

NPM install [email protected]Copy the code

You can view all versions through Webpack Info


Three, start packing

Once webpack is installed, we can start packaging our project code, such as an xxx.js file in our project.

npx webpack xxx.js 
Copy the code

This will package one of the JS files, which will be stored in the dist folder at the root of the project. This is the basic packaging of WebPack, using the default configuration of WebPack. If you want more functionality, you can configure it in the webpack.config.js file


4. Configuration files

Create a new webpack.config.js file in the project root directory.

const path = require('path');

module.exports = {
	mode: 'production'.In production mode, JS is not compressed
	// entry: Specifies the entry file,
	entry: { // Package output two files
		home: './src/index.js'.index: './src/index.js'
	},
	output: { // Output configuration
		publicPath:'http://cdn.com.cn'.// Specify the prefix address of the packaged file
		filename:'[name].js'.// The name of the packed file, which can be placeholder by placeholder, [name] gets the name of the entry configuration
		path: path.resolve(__dirname, 'dist') // The packaged folder is dist by default}}Copy the code

This is the packaging configuration of the latest version, the specified packaging mode, entry, output configuration, etc. Once configured, it can pass

npx webpack
Copy the code

Run directly, no longer need to write a specific file, but through the configuration entry to find the specified file. Webpack.config. js is the default webpack configuration file. You can also manually modify the command line by running the following command: NPX webpack –config webPackConfig2.js

NPX webpack is rarely used in development because it is simplified in package.json. Add the following code to scripts

"scripts": {
   "bundle": "webpack"
},
Copy the code

NPM run bundle is equivalent to webpack. Using Webpack in scripts takes precedence over looking for Webpack in the project’s node_modules.

When we installed webpack, we installed a webpack-CLI package. This webpack-CLI package allows us to run webpack commands (NPX webpack, etc.) from the command line.


Five, the loader

Webpack’s job is to pack, but WebPack can only recognize JS files, and if we introduce styles into our JS file, or try to pack a CSS file, image file, etc., then WebPack will report an error. Because WebPack doesn’t know how to handle such files. At this point, WebPack needs one thing to help it process, which is loader. ==loader helps Webpack unrecognized files ==

Packaging CSS

css-loader & style-loader

const path = require('path');

module.exports = {
	mode:...entry:... .output:... .module: {rules:[
			{
				test: /\.css$/,
				use: ['style-loader'.'css-loader'}]}}Copy the code

To package CSS files, install style-loader and CSS-loader.

npm install style-loader css-loader -D
Copy the code

The Rules array is a bunch of packing rules that are matched to a CSS file by regular expression, and then tells Webpack to use style-loader and CSS-loader whenever it encounters a CSS file. Css-loader is used to help WebPack recognize CSS. Analyze file relationships and merge them. Style-loader is used to obtain the analysis result of CSS-loader and mount the CSS to htML-header-style. == Therefore, loader is invoked in sequence from back to front. Css-loader is executed first and then style-loader is executed.

Sass-loader The sASS -loader is used to package SASS files. First, install sass-Loader and Node-sass. NPM I sass-loader node-sass -d then modify rules

rules:[
	{
		test: /\.css$/,
		use: [
				'style-loader',
				{
					loader: 'css-loader'.options: {
						importLoaders: 1.modules: true // By default, the imported CSS is global. When true is enabled, the CSS becomes modular}},'sass-loader']}]Copy the code

Sass-loader must be called before CSS-loader, so it must be placed at the end of the array. However, if an SCSS file is imported from another SCSS file, the second SCSS file will go directly to CSS-Loader during packaging, resulting in packaging failure. Therefore, add importLoaders in options of CSS-Loader to indicate that another loader needs to be loaded before going to CSS-Loader.

Postcss-loader The postCSs-loader can automatically add the cSS3 prefix. You need to create a postcss.config.js file and install the plug-in. NPM I autoprefixed -d place postCSs-loader before sass-loader in rules. postcss.config.js

module.exports = {
    plugins: [require('autoprefixer')]}Copy the code

This will automatically add the CSS3 prefix when we package our CSS code. Because the browser compatibility table is built into Autoprefixer, the default is >5% compatibility.

The packaged file

File-loader & url-loader Install NPM I file-loader -d. Pack the image file below

rules: [
	{
		test: /\.(jpg|png|gif)$/,
		use: {
			loader: 'file-loader'.option: {
				name: '[name]_[hash].[ext]'.outputPath: 'images/'}}}]Copy the code

Placeholder names are placeholder names. If you do not specify the placeholder name, the packed file will be randomly generated. For very small images, you can use urL-loader to package them in base64 format and put them in JS files. NPM I url-loader -d is installed first. The url-loader function of file-loader can also be implemented. If the size limit is set, the url-loader is packaged in traditional mode; otherwise, it is packaged in Base64 mode.

rules: [
	{
		test: /\.(png|jpg|gif)$/,
		use:{
			loader: 'url-loader'.options: {name: '[name]_[hash].[ext]'.outputPath: 'images/'.limit: 2048 // Limit the file size to 2048 bytes and use base64 packaging}}}]Copy the code
Packaging es6

Install the babel-Loader and Babel /core packages. NPM I babel-loader @babel/core -d babel-loader is a tool to help webpack packaging. You can tell Babel to recognize the syntax in JS and convert the JS syntax into an AST abstract syntax tree. Add babel-loader to analyze JS syntax, get through Babel and Webpack, and use other Babel modules to convert ES6 to ES5. Install Babel /preset-env NPM i@babel /preset-env -d and ES6 can now be converted to ES5, but some preset methods are still not supported in older browsers. You also need to use the Polyfill module. NPM i@babel /polyfill -d then introduces the polyfill import “@babel/polyfill” in the business code and overwrites webpack.config.js

rules: [
	{
		test: /\.js$/,
		exclude: /node_modules/.// exclude code in node_modules
		loader: 'babel-loader'.options: {presets: [["@babel/preset-env"] and {targets: {chrome: "67" > // Compatible browser versions can be specified
			 	},
			 	// When polyfill is used, all features are added, rather than depending on the business code, resulting in large packaged files. So solve this problem with the following configuration, which packages the features used according to the needs of the business code
			 	useBuiltIns: 'usage'}}}]]Copy the code

Now you can package your ES6 code normally. However, there is a potential problem that polyfill reinjection is done in the form of global variables, which contaminates the global environment and is not suitable for component packaging. NPM I @babel/ plugin-transform-runtime@babel/runtime@babel/runtimecorejs2 -d add plugins to Babel options.

rules: [
	{
		test: /\.js$/,
		exclude: /node_modules/,
		loader: 'babel-loader'.options: {// Library code uses this configuration to solve the polyfill problem
			"plugins": [["@babel/plugin-transform-runtime"] and {"corejs": 2."helpers": true."regenerator": true."useESModules": false}}}]]Copy the code

Add: The configuration in options can be placed separately in the. Babelrc file


Sixth, the plugin

Plugins are similar to lifecycle functions in some frameworks that trigger to do something at a specific point in time when the package is packaged.

HtmlWebpackPlugin such as html-webpack-plugin is at the end of the packaging. Install the plug-in. NPM I html-webpack-plugin -d HtmlWebpackPlugin automatically generates an HTML file after packaging, and automatically introduces the JS generated by packaging into the HTML. There are no tags in the HTML. You can also use the template template to generate HTML files using the configured HTML file as the template.

const path = require('path');

module.exports = {
	mode:...entry:... .output:... .module:... .plugins: [
		new HtmlWebpackPlugin({
			// Generate HTML files from the template
			template: 'src/index.html'}})]Copy the code

CleanWebpackPlugin The CleanWebpackPlugin removes (unofficially) the dist directory before packaging. CNPM I clean-webpack-plugin-d

module.exports = {
	mode:...entry:... .output:... .module:... .plugins: [
		Delete the dist directory first
		new CleanWebpackPlugin(['dist'])]}Copy the code

Seven, sourceMap

SourceMap is a mapping that knows the location of the error in the main. Js file in dist corresponds to the location of the index.js file in SRC. Add the devTool configuration in webpack.config.js.

module.exports = {
	mode:...devtool: 'none'
}
Copy the code

Setting devtool: ‘None’ will only prompt js errors in the packaged JS file, making it extremely difficult to locate errors at development time. If devtool is set to ‘source-map’, js errors will be displayed in the original file, because a map.js file will be generated in the packaged directory where the mapping is stored. Locate the original file by mapping when an error is reported. Set devtool to ‘inline-source-map’, inline will not generate a map file, but a Base64 string stored at the bottom of the packed JS file. Set devtool to ‘cheap-source-map’. If cheap is not set, the error message will be specific to the row and column, resulting in a complex mapping relationship and a cost of performance. Adding cheap solves this problem while not dealing with third-party code, just business code. To some business needs to write our own module or third party code for processing. That’s the Module. Set devtool to ‘cheap-module-source-map’. Set module to solve cheap and not handle third-party modules. If devtool is set to ‘cheap-module-eval-source-map’, eval will not generate a map file or a Base64 encoded string. Instead, it will change the way the code is executed and point to the original file via sourceURL. Best performance. == devtool: ‘cheap-module-eval-source-map’ == devtool: ‘cheap-module-source-map’ == devtool: ‘cheap-module-source-map’


Eight, devServer

Having to manually repackage after each change is a huge waste of time. There are three ways to solve this problem

1. Add it to package.json"watch": "webpack --watch"

scripts:{
   "watch": "webpack --watch"
}
Copy the code

Run the command NPM run watch while packing and WebPack will listen for the files to be packed and repack them if they change.

2. Configure devServer and install dev-server. NPM I webpack-dev-server -d adds configuration in package.json

scripts:{
   "start": "webpack-dev-server"
}
Copy the code

Run the command NPM run start while packing and also add configuration to webpack.config.js,

module. Exports = {...devServer: {
		contentBase: './dist'.// Package the file directory
		open: true.// Whether to open the browser automatically
		prot: 8080 // Start the service port}}Copy the code

== Webpack-dev-server does not generate the dist directory when packaged, but in memory. Improve packaging speed = = use the dev – server can match use Hot Module Replacement (Hot Replacement Module) is introduced into HotModuleReplacementPlugin plug-in, can open HMR function, HMR can heat more js and CSS code.

module. Exports = {...devServer: {
		contentBase: './dist'.// Package the file directory
		open: true.// Whether to open the browser automatically
		prot: 8080.// Start the service port
		hot: true./ / open HMR
		hotOnly: true // Prevents the browser from automatically refreshing
	},
	plugins: [
		new webpack.HotModuleReplacementPlugin()
	],
}
Copy the code

3. Write your own node service such as server.js, configure the server command “server” in package.json: “Node server.js”, which is equivalent to NPM run server when using webpack in node.

Nine,

These are the basic webPack uses, and this article covers enough of the packaging needs of a small project. Once you have mastered the basics, you can read the official WebPack documentation for a more detailed packaging configuration.