webpack-dev-server
To realize the automatic compilation and display of files modified during development, you can use the live server plug-in with webpack's watch attribute of true and vscode, that is, observation mode
// webpack.config.js module.exports = { watch: true, ... }
However, this has several disadvantages:
- All source code is recompiled
- Because we use the clean webpack plugin plug-in, we need to read and write the file after each successful compilation
- live server is a vscode plug-in. We should use Webpack plug-in
- live server cannot achieve local refresh
For the above reasons, we use webpack dev server, which writes all data in memory;
npm install webpack-dev-server -D
Note that the commands configured here are different from the yarn webpack dev server of webpack 4
// package.json "scripts": { "serve": "webpack serve --config lg.webpack.js" }
webpack-dev-middleware
Webpack dev middleware is a wrapper that can send files processed by webpack to a server. Webpack dev server uses it internally, but it can also be used as a separate package for more customization as needed. The following is an example of webpack dev middleware cooperating with express server.
const express = require('express') const webpackDevMiddleware = require('webpack-dev-middleware') const webpack = require('webpack') const app = express() // Get profile const config = require('./webpack.config.js') const compiler = webpack(config) app.use(webpackDevMiddleware(compiler)) // Turn on the service on the port app.listen(3000, () => { console.log('The service runs on port 3000') })
HMR function usage
hot module replacement (HMR) is one of the most useful functions provided by webpack. It allows all types of modules to be updated at run time without a full refresh.
Note: because we configure the Mode as development in the development phase, it is different from our configuration The compatibility of the browserlistrc file is in conflict. The official suggests that we use taget: 'web' to solve it;
Configuring the hotOnly property will not refresh the browser whether it is updated or not.
// webpack.config.js module.exports = { target: 'web', devServer: { hot: true, // hotOnly: true } ... }
The hot update of the module needs to be manually configured in the file, as follows:
import './title' if (module.hot) { module.hot.accept(['./title.js'], () => { console.log('title.js Module update') }) }
Title When an update occurs in JS, the console. Exe will be triggered Log ('title.js module update ') and has the effect of hot update;
React component supports hot update
In react, we need to compile jsx syntax
npm install @babel/preset-react -D
For the hot update of react component, we are officially required to download two plug-ins
npm install @pmmmwh/react-refresh-webpack-plugin react-refresh -D
// babel.config.js module.exports = { presets: [ ['@babel/preset-env'], ['@babel/preset-react'], ], plugins: [ ['react-refresh/babel'] ] }
// webpack.config.js ... const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin') module.exports = { ..., target: 'web', devServer: { hot: true }, module: { rules: [ ..., { test: /\.jsx?$/, use: ['babel-loader'] } ] }, plugins: [ ..., new ReactRefreshWebpackPlugin() ] }
Question? The value in input was lost during hot update of React component
Vue components support hot updates
npm install vue-template-compiler vue-loader vue -D
vue2. Version 0 + Vue loader 15 consists of three steps: configure Vue loader, configure Vue loader plug-in, and install Vue template compiler plug-in;
compile. vue syntax. vue loader and vueLoaderPlugin plug-ins need to be configured
To solve the problem of Cannot read property 'parseComponent' of undefined error, you need to install Vue template compiler
reference material: https://vue-loader.vuejs.org/zh/guide/#vue-cli
... const VueLoaderPlugin = require('vue-loader/lib/plugin') module.exports = { ..., target: 'web', devServer: { hot: true }, module: { rules: [ ..., { test: /\.vue$/, use: ['vue-loader'] } ] }, plugins: [ ..., new VueLoaderPlugin() ] }
// "vue-template-compiler": "^2.6.14",
path in output
publicPath is to inform index Where will HTML go to find the resources you want to load in the future
localhost:8080 + '/' + 'js/main.js'
Local server + publicPath + filename
If publicPath is not configured, the browser will automatically spell '/', so it can be manually configured as' / ', but at this time, the packaged file after npm run build cannot be opened locally; In order to open the package file locally, you can configure '. /' for publicPath, However, npm run serve cannot run at this time, because it will start looking for JS / main from the current directory JS file cannot be found;
path in devserver
When devserver runs, the files will be packaged in a virtual directory, and the public path of output is configured with index HTML to find the path after packaging (at this time, the resources not packaged by webpack cannot be found in the virtual directory, and the contentBase needs to be configured). The publicPath in devserver configures the directory where devserver will find, and the contentBase in devserver configures index Resource paths that are not packaged by webpack but are introduced in HTML;
publicPath: tells devServer which directory to look for, that is, the packaged files will be placed in a virtual '/ lg' (publicPath) directory;
The default value is' / '. It is strongly recommended that the publicPath in output and the publicPath of devServer be set to the same value; After configuration, you should access http://localhost:8080/lg ;
**contentBase: * * if our packaged resources depend on other resources, we will tell them where to find them (for example, if we introduce files not processed by webpack into index.html file, we will tell index.html where to find these dependent resources, generally using absolute path);
**watchContentBase: * * used in combination with contentBase. The default value is false. When we modify the resources that the packaged resources depend on, the page will change with it. The default is that the modified resource page will not be updated in time;
output: { filename: 'js/main.js', path: path.resolve(__dirname, 'dist'), publicPath: '/lg' }, target: 'web', devServer: { hot: true, publicPath: '/lg', // contentBase: path.resolve(__dirname, 'public'), // watchContentBase: true, open: true },
here http://localhost:8080 No access, but access http://localhost:8080/lg You can access the page, http://localhost:8080/lg/js/main.js You can find the packaged resources;
devServer common configuration
hotOnly: do not refresh anyway;
**compress: * * enable g-zip compression;
**historyApiFallback: * * when using browserRoute mode, refreshing may cause page 404;
Proxy proxy settings
When starting the local server, cross domain problems will occur in the access interface;
**pathRewrite: * * rewrite the path;
**changeOrigin: * * modify the host name;
devServer: { hot: true, hotOnly: true, port: 4000, open: false, compress: true, historyApiFallback: true, proxy: { // /api/users // http://localhost:4000/api/users // https://api.github.com/info/users // /API / users --- > Return '/api': { target: 'https://api.github.com', pathRewrite: { "^/api": "" }, changeOrigin: true } } },
resolve module parsing rules
File lookup has three mechanisms by default
- Relative path
- node_modules
- Absolute path
extensions: file extension name. When we don't write the file suffix, we will look here;
Alias: path alias setting;
resolve: { extensions: [".js", ".json", '.ts', '.jsx', '.vue'], alias: { '@': path.resolve(__dirname, 'src') } },
Source map function
When the mode is development, the default devtool is eval
The mode is: [inline - | hidden - | eval -] [nosources -] [heap - [module -]] source map
Source map in vue
In react, it is a heap module source map
Compiling ts with TS loader
npm install typescript ts-loader -D
At this time, both TS loader and Babel loader can be used, but TS loader cannot plyfill;
Babel loader can't verify the data type, and if the syntax is wrong, it will be packaged successfully. However, when we use TS loader, it will be verified during packaging, so that we can find the problem earlier;
Official suggestion: just convert the syntax and use TS loader, but if we need to use polyfill, we can use Babel loader;
Using Babel loader, you can do a verification first in package Add ts syntax verification in JSON. tsc --noEmit can only verify, not package into js files; This will help us check the ts syntax before executing num run build. If there is an error, it will not be packaged;
// package.json "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "npm run ck && webpack", "serve": "webpack serve", "ck": "tsc --noEmit" },
module: { rules: [ { test: /\.jsx?$/, use: ['babel-loader'] }, { test: /\.ts$/, use: ['babel-loader'] } ] },
// babel.config.js is configured with polyfill and ts parsing module.exports = { presets: [ ['@babel/preset-env', { useBuiltIns: 'usage', corejs: 3 }], ['@babel/preset-typescript'] ] }
Load vue file
Refer to Vue component support hot update section;
vue2. Version 0 + Vue loader 15 consists of three steps: configure Vue loader, configure Vue loader plug-in, and install Vue template compiler plug-in;