The Plugin plug-in
Loader enables WebPack to handle more file resources throughout the webpack process. Plugin exists in the entire WebPack packaging process. The content being processed can be processed at the moment a hook is triggered by webpack exposure. So we can use plugin to do all sorts of things with the files we are processing.
Processing of index.html files
Previously we made a copy of index.html to the dist folder. If index.html needs to be changed dynamically, this is not a good process. We can use a plug-in HtmlWebpackPlugin to generate our packed HTML file and process the project file.
project
webpack-demo
|- package.json
|- package-lock.json
|- /dist
|- main.js
|- main.js.LICENSE.txt
- |- index.html
|- /src
|- icon.png
|- index.less
|- index.js
|- webpack.config.js
|- postcss.config.js
|- .browserslistrc
+ |- index.html
Copy the code
Install the appropriate plug-in dependencies
npm install --save --dev html-webpack-plugin
Copy the code
webpack.config.js
+ const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
...
+ plugins: [
+ new HtmlWebpackPlugin({
+ template: path.join(__dirname, "./index.html"), //./index.html is used as a template to generate dist/index.html+}), +],... };Copy the code
index.html
<! DOCTYPE html><html>
<head>
<meta charset="utf-8" />
<title>Getting Started</title>
</head>
<body></body>
</html>
Copy the code
Re-run the NPM run build and view the dist/index.html file.
<! doctype html><html><head><meta charset="utf-8"/><title>Getting Started</title><script defer="defer" src="main.js"></script></head><body></body></html>
Copy the code
You can see that the main.js file is inserted with the script tag. This is what the HtmlWebpackPlugin plugin inserted in dist/index.html. Of course, the plugin also has some interesting ways to dynamically generate index.html, which is left to the reader to explore.
Hot update configuration
Every time we changed the source code, WebPack had to repackage the file and refresh the browser to see the effect, which was a terrible experience for developers. We can use hot updates to improve the development experience. When we make changes to the source code, hot updates allow our changes to show up quickly in the browser. Webpack provides three ways to implement hot updates. In this case, we currently use webpack-dev-server. Other ways can be found here.
Install dependencies
npm install --save --dev webpack-dev-server cross-env
Copy the code
Install dependencies on webpack-dev-server, which is used to provide hot update services, and cross-env, which is used to easily inject variables in the package.json command line.
webpack.config.js
module.exports = {
output: {... }, + target:"web",
+ mode: "development",
+ devtool: "inline-source-map",
+ devServer: {
+ contentBase: path.resolve(__dirname, "dist"),
+ hot: "localhost",
+ compress: true,
+ port: 3002, +},module: {... }};Copy the code
- Mode: configuration environment, including development and production modes. If this parameter is not set, the production mode is set by default.
- Devtool: controls whether the source map is generated. With source Map, we can effectively debug the source map in the browser in the development environment, but in the production environment, it is recommended to disable.
- DevServer: configuration of the development environment. For details, you can go to the official website.
package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"."build": "webpack",
+ "dev": "cross-env NODE_ENV=development webpack serve --progress --hot --config webpack.config.js"
},
Copy the code
NODE_ENV= after cross-env can be set to the environment variable when Webpack runs in Node. –config is the webPack configuration file that is specified to execute.
Run the command line NPM run dev in the terminal. The terminal displays after the operation is successful.
Project is running at http://localhost:3002/ℹ "WDS" : Webpack output is servedfrom/ ℹ "WDS" : Content notfrom webpack is served from /Users/liwangping/Desktop/study/webpack-demo/dist
Copy the code
The above lines of output show that the project is running at http://localhost:3002/. Click open. Then try to change the code in the source file.
src/index.js
function component() {...// Lodash, currently included via a script, is required for this line to work
- element.innerHTML = _.join(["Hello"."webpack"]."");
+ element.innerHTML = _.join(["Hello1"."webpack"].""); . }document.body.appendChild(component());
Copy the code
After the change, save the file and then observe the browser.
At this point, the hot update is successful, as is changing the properties in the LESS file.
src/index.less
body {
- background-color: red;
+ background-color: blue;
transition: background-color .4s;
}
Copy the code
Page shows
Webpack configuration file separation
In the current webpack.config.js configuration, we currently implement the dev environment configuration, but it should not be the same for development and production environments, such as source map should not be present in production environments. Webpack-dev-server should also not be in production. But at the same time, production and development have some of the same configuration, so we can split the WebPack configuration file into three files. A common configuration file is written with two different environment configuration files, and when used, that same configuration file is combined with the development environment configuration file to complete the development environment configuration. The production environment is the same. To do this, we need to use the Webpack-Merge plug-in that merges the WebPack configuration files.
Install dependencies for merging different WebPack configuration files
npm install --save --dev webpack-merge
Copy the code
project
webpack-demo
|- package.json
|- package-lock.json
|- /dist
|- main.js
|- main.js.LICENSE.txt
|- /src
|- icon.png
|- index.less
|- index.js
|- postcss.config.js
|- .browserslistrc
|- index.html
- |- webpack.config.js
+ |- webpack.common.js
+ |- webpack.dev.js
+ |- webpack.build.js
Copy the code
webpack.common.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.js".// The entry to the package file from which WebPack will start to analyze the dependency structure of the entire project
output: {
filename: "main.js".// The output file name
path: path.resolve(__dirname, "dist"), // Output folder
},
module: {
rules: [{test: /\.(css|less)$/i,
use: [
{
loader: "style-loader"}, {loader: "css-loader"}, {loader: "postcss-loader"}, {loader: "less-loader",},],}, {test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: "asset/resource"}, {test: /\.(png|svg|jpg|gif)$/i,
type: "asset/resource"}, {test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: "asset/resource"}, {test: /\.(csv|tsv)$/i,
use: ["csv-loader"],}, {test: /\.xml$/i,
use: ["xml-loader"],},],},plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, "./index.html"), //./index.html is used as a template to generate dist/index.html})]};Copy the code
webpack.dev.js
const { merge } = require("webpack-merge");
const path = require("path");
const common = require("./webpack.common");
module.exports = merge(common, {
target: "web".mode: "development".devtool: "inline-source-map".devServer: {
contentBase: path.resolve(__dirname, "dist"),
hot: "localhost".compress: true.port: 3045,}});Copy the code
webpack.build.js
const { merge } = require("webpack-merge");
const common = require("./webpack.common");
module.exports = merge(common, {
mode: "production"});Copy the code
package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
- "build": "webpack",
+ "build": "cross-env NODE_ENV=production webpack --progress --config webpack.build.js",
- "dev": "cross-env NODE_ENV=development webpack serve --progress --hot --config webpack.config.js"
+ "dev": "cross-env NODE_ENV=development webpack serve --progress --hot --config webpack.dev.js"
},
Copy the code
Run NPM run dev and NPM run build respectively.
Babel configuration
Babel is designed to make the most of the latest JS syntax we write across browsers. Because different browser vendors have different levels of support for the ES syntax standard, Babel smoothen the differences at the bottom, allowing us to use new syntax in projects without worrying about compatibility issues.
Let’s install Babel for the WebPack project.
So far all we need is the smart preset set of the smallest set. So @babel/preset-env is enough for now, and more configurations can be found on Babel’s official website.
project
webpack-demo
|- package.json
|- package-lock.json
|- /dist
|- main.js
|- main.js.LICENSE.txt
|- /src
|- icon.png
|- index.less
|- index.js
|- postcss.config.js
|- .browserslistrc
|- index.html
|- webpack.common.js
|- webpack.dev.js
|- webpack.build.js
+ |- babel.config.json
Copy the code
Install dependencies
npm install --save-dev babel-loader @babel/core
Copy the code
webpack.common.js
module.exports = {
...
module: {
rules: [{...test: /\.xml$/i,
use: ["xml-loader"],
},
+ {
+ test: /\.js$/,
+ exclude: /node_modules/,
+ use: {
+ loader: "babel-loader", +}, +},],},plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, "./index.html"), //./index.html is used as a template to generate dist/index.html})]};Copy the code
Install the @babel/preset-env dependency
npm install @babel/preset-env --save-dev
Copy the code
babel.config.json
{
"presets": ["@babel/preset-env"]}Copy the code
Then run NPM run dev to start writing code for the new syntax.
Support the react
React is easy to configure because Babel has the ability to convert JSX syntax to JS. After installing the React core library, modifying the entry file, and configuring Babel to support JSX syntax, we can write React in our project.
project
webpack-demo
|- package.json
|- package-lock.json
|- /dist
|- main.js
|- main.js.LICENSE.txt
|- /src
|- icon.png
|- index.less
- |- index.js
+ |- index.jsx
|- postcss.config.js
|- .browserslistrc
|- index.html
|- webpack.common.js
|- webpack.dev.js
|- webpack.build.js
|- babel.config.json
Copy the code
Install react dependencies
npm install --save react react-dom
Copy the code
src/index.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import './index.less';
const App = () = > {
return <div>App134</div>;
};
ReactDOM.render(<App />.document.getElementById("root"));
Copy the code
index.html
<! DOCTYPE html><html>
<head>
<meta charset="utf-8" />
<title>Getting Started</title>
</head>
<body>
+ <div id="root"></div>
</body>
</html>
Copy the code
Add a root node to make the REACT generated DOM mount on the div with the root id.
Install Babel so react JSX files can be processed
npm install --save-dev @babel/preset-react
Copy the code
babel.config.json
{-"presets": ["@babel/preset-env"]
+ "presets": ["@babel/preset-env"."@babel/preset-react"]}Copy the code
Added react preset set @babel/preset-react.
webpack.common.js
module.exports = {
- entry: "./src/index.js".// The entry to the package file from which WebPack will start to analyze the dependency structure of the entire project
+ entry: "./src/index.jsx".// The entry to the package file from which WebPack will start to analyze the dependency structure of the entire project.module: {
rules: [
...
{
- test: /\.js$/,
+ test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",},},],},... };Copy the code
Modify the entry and file format matched by loader. Then run NPM run dev and the JSX file is parsed successfully.
Support for ts
The idea of supporting TS is also simple, as TS can also be converted to JS via Babel, as can TSX. So we just need to support TS/TSX on our existing Babel setup, and we can write ts/ TSX files.
peoject
webpack-demo
|- package.json
|- package-lock.json
|- /dist
|- main.js
|- main.js.LICENSE.txt
|- /src
|- icon.png
|- index.less
- |- index.jsx
+ |- index.tsx
|- postcss.config.js
|- .browserslistrc
|- index.html
|- webpack.common.js
|- webpack.dev.js
|- webpack.build.js
Copy the code
Change the name of the index.jsx file under SRC to index.tsx.
Install dependencies
npm install --save-dev @babel/preset-typescript
Copy the code
webpack.common.js
module.exports = {
output: {
filename: "main.js".// The output file name
path: path.resolve(__dirname, "dist"), // Output folder
},
+ resolve: {
+ extensions: [".ts".".tsx".".js".".json"] +},module: {
rules: [{...test: /\.xml$/i,
use: ["xml-loader"],
},
{
- test: /\.(js|jsx)$/,
+ test: /\.(ts|tsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",},},],},... };Copy the code
Add the tsconfig configuration file
{
"compilerOptions": {
"outDir": "./dist/"."sourceMap": true."noImplicitAny": true."esModuleInterop": true."module": "commonjs"."target": "es5"."noUnusedLocals": true."jsx": "react"
},
"include": [
"./src/**/*"]}Copy the code
If you need more configurations, refer to this.
Note: The editor opens SRC /index.tsx if you see an error
Could not find a declaration file for module 'react'. '/Users/*********/Desktop/study/webpack-demo/node_modules/react/index.js' implicitly has an 'any' type.
Try `npm i --save-dev @types/react` if it exists or add a new declaration (.d.ts) file containing `declare module 'react'; `ts(7016)
Copy the code
Install @types/react. Install @types/react. Install @types/react. NPM I — save-dev@types /react Other similar errors are treated in the same way. Here is just an example, specific look at your own need to install the package, such a tip solution is the same treatment. NPM I — save-dev@types/NPM package name
At this point, the TS support environment is ready, run it and try it out.
A simple WebPack environment has now been configured. Of course, now this is far from enough, there are some configuration needs to continue, such as:
- Jest unit test environment setup
- Alias Alias unification
- Eslint,stylelint syntax configuration
- . Prettierrc Style configuration
- Repair and validation of submitted files during HusKY triggered Lint-staged periods
- Mock. Js environment setup
- Webpack performance optimization section (build, development, output, etc.)
, etc.
We will continue to refine these later. Hope everyone can not understand the question directly comment, or issue better. All commit records will be placed on Git. Follow the entire setup process. I hope I can help you. Welcome star, comments. Your likes are the biggest motivation for me to write.