Moment For Technology

Webpack4.0 CheatSheet

Posted on June 24, 2022, 3:13 a.m. by Norman Roberts
Category: The front end Tag: webpack

Bothered by webPack configuration? Here is a configuration of WebPack from easy to advanced. It comes with a configuration address. Do you want one? No, you don't. Do your own configuration.

The create-React-app webPack configuration is a good example of how to configure webpack. And learned how to write a simple proxy yourself.

Loaders all configuration

Loader role
html-loader ---
html-webpack-plugin ---
style-loader ---
mini-css-extract-plugin The extract-text-webpack-plugin will no longer be used after Webpackage 4.0
css-loader A CSS into JS loader, I think its modules is a very practical function, big love
sass-loader An SASS processor that compiles SCSS to CSS, and then CSS does further processing
node-sass Compile SCSS dependent packages
postcss-loader One for Autoprefix,autoprefixer.github.io/Automatically add annoying prefixes to CSS
ts-loader If ts is compiled without Babel, ts-Loader is required
file-loader Import files, such as JSON, into JS format
url-loader Similar to file-loader, but smarter than file-loader, if the file is too large, only one address can be loaded without loading the file
babel-loader Stop it. Es6 needs him to compile
webpack Everybody gets it. The core
webpack-cli It's easy to start compiling

Babel configuration

Binary now compiles JS directly

npx babel src --out-dir lib
Copy the code

Tell me out loud what does Babel do? Because JS syntax is constantly evolving, and browsers don't update as often as JS syntax, a compiler is needed to make JS syntax compatible with browsers that support different generations of JS syntax.

npm install --save-dev @babel/core @babel/cli @babel/preset-env
npm install --save @babel/polyfill
npm install --save-dev bable-loader
Copy the code
@babel/polyfill vs @babel/preset-env
Ignore the syntax and require the missing API Save all kinds of novel writing (such as arrow functions), not APIS
Core packages core/js

@babel/preset-env

babel-preset-es2015
babel-preset-es2016
babel-preset-es2017
babel-preset-latest
A combination of the above ^
....
Copy the code

Nightmare configuration. When I first learned Babel, I looked at these configurations and vaguely thought I couldn't learn them. But now babel-Preset -env will do it all! .

@ Babel/plugin - proposal - class - the properties babeljs. IO/docs/en/bab...

@babel/polyfill

This package has been removed by Babel and is simply an alias for core-js.

Other plugin

The REACT all configuration

Just install one more Babel


npm install --save-dev @babel/preset-react
npm install --save-dev react react-dom
Copy the code

TS all configuration

npm install --save-dev typescript
Copy the code

Ts can be compiled with Babel

npm install --save-dev @babel/preset-typescript
Copy the code

Ts can also be compiled with TS-loader. Tsconfig.js is required

npm install --save-dev ts-loader
Copy the code

Some insights on CSS loading

CSS loaders can be very simple or very complex. The general requirements are as follows:

  • Effective CSS, load directly inline
  • You want to be able to generate a separate file and then load the URL
  • I hope I can compress it
  • Want automatic prefix function
  • Use advanced CSS processors such as SCSS

The create-react-app configuration file is used to create a CSS loader.

// mini-css-extract-plugin,有了他可以代替style-loader,不仅压缩了文件,还可以帮助我们将CSS从js中剥离出来
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // Loaders should be preprocessed first, such as Scss, and then prefixed with prefix. So far, CSS is still the same as CSS. After csS-loader, CSS becomes JS. Finally, style-loader or MinicSS will turn CSS modules into JS generated files or inline. Const getStyleLoaders = (cssOptions, preProcessor,env) = {const loaders = [// Here is the last step to extract or inline the CSS {loader:env==="development"? require.resolve('style-loader') : MiniCssExtractPlugin loader}, / / CSS into standard JS module here, if there is a CSS modularity requirements, in this processing {loader: the require. Resolve ('css-loader'Resolve (loader: require.resolve(loader: require.resolve(loader: require.resolve)), options: cssOptions,},'postcss-loader'),
            options: {
                ident: 'postcss',
                plugins: () = [
                require('postcss-flexbugs-fixes'),
                require('postcss-preset-env')({
                    autoprefixer: {
                    flexbox: 'no-2009', }, stage: 3, }), ], }, }, ]; // If sASS is required, you need to configure it hereif (preProcessor) {
        loaders.push(require.resolve(preProcessor));
    }
    returnloaders; }; // style files regexes const cssRegex = /\.css$/; const cssModuleRegex = /\.module\.css$/; const sassRegex = /\.(scss|sass)$/; const sassModuleRegex = /\.module\.(scss|sass)$/; . / / export to webpack configuration using the module exports = {getStyleLoaders cssRegex, cssModuleRegex, sassRegex, sassModuleRegex}Copy the code

HMR hot update configuration - Reduces manual compilation of refresh pages

Webpack comes with a server

npm install --save-dev webpack-dev-server
Copy the code
devServer: {
    contentBase: path.join(__dirname, 'dist1'),
    compress: true,
    hot: true,
    port: 9000
},
entry: [
    require.resolve('webpack-dev-server/client') + '? / ',
    require.resolve('webpack/hot/dev-server'),
    path.resolve(__dirname,'src/index')
],
plugins: [
    new webpack.HotModuleReplacementPlugin()
]
Copy the code

Cross-domain issues with webpack's built-in servers

devServer: {
    proxy: {
      '/slider': {
          target: 'http://www.cherryvenus.com/',
          secure: false,
          changeOrigin: true//important to solve most 404 problems}}},Copy the code

Custom server

npm install --save-dev express webpack-hot-middleware webpack-dev-middleware
Copy the code

The client, webpack, is a plugin-like program that links to webSockets. Remove this from production, otherwise the bundle will be very large.

entry: [
    require.resolve('webpack-hot-middleware/client') + '?path=/__whattimeout=2000overlay=false',
    path.resolve(__dirname,'src/index')
],
plugins: [
    new webpack.HotModuleReplacementPlugin()
]
Copy the code

Server: The path must be the same as that of the client.

app.use(require("webpack-hot-middleware")(compiler,{
  log: false,
  path: "/__what",
  heartbeat: 2000
}));
Copy the code

The client module of the entry entry is added. If you do not accept, the program cannot be refreshed automatically.

if(module.hot){
  module.hot.accept()
}
Copy the code

Http-proxy-middleware - Addresses cross-domain issues in development

npm install --save-dev http-proxy-middleware
Copy the code
var proxyMiddleWare = require("http-proxy-middleware");
var proxyPath = "http://www.cherryvenus.com/";
var proxyOption ={target:proxyPath,changeOrigoin:true};
app.use(proxyMiddleWare("/slider",proxyOption))
Copy the code

Proxy research at the bottom of the box

Proxy configuration development based on third-party plug-ins

Both http-proxy-middleware and Webpack-dev-server proxies are based on HTTP-proxy-middleware, while http-proxy-middleware is based on Node-HTTP-proxy.

Reference website:

Github.com/nodejitsu/n...

Github.com/chimurai/ht...

var proxyPath = "http://www.cherryvenus.com/";
var proxyOption ={target:proxyPath,changeOrigin:true,selfHandleResponse : true,ignorePath:true}; Const proxy = httpProxy. CreateProxyServer ({}) / / if selfHandleResponse fortrueIt is the content that can be modified by itself. If you do not need to modify it, you do not need to set it. // If you want to customize the retrieved content, you can intercept the content by triggering the event 'proxyRes' and modify proxy.on('proxyRes'.function (proxyRes, req, res) {
    var body = new Buffer(' '); // Here I copy the header information, saving a wave of configurationfor(let i in proxyRes.headers){
        res.setHeader(i, proxyRes.headers[i]);
    }
    proxyRes.on('data'.function (data) {
        body = Buffer.concat([body, data]);
    });
    proxyRes.on('end'.function () {
        body = Buffer.from(body);
        res.write(body);
        res.end()
        res.rs()
    });
    proxyRes.on('error'.function (err, req, res) {
        res.writeHead(500, {
          'Content-Type': 'text/plain'
        });
        res.end('Something went wrong. And we are reporting a custom error message.'); }); }) // Here is only a link configured, the real trigger proxy, is proxy.web(req, res, proxyOption); app.use("/slider/",(req, res, next)={// When the address status goes toletP = new Promise((rs,rj)={// close the previous proxy, if proxy.close(); Res.rs =rs // Request a new link proxy.web(req, res, proxyOption); }) p.then(()={ next() })return p
})
Copy the code

Write one manually

When I saw the above solution, I suddenly had a flash of inspiration. Could I write one myself? This process is not complicated. In fact, proxy is the process of grabbing and forwarding web pages. In this case, it is not difficult to write a simple proxy.

const http=require("http") // createServer http.createserver ({host:'localhost'}, (req, res) = {// Open a request http.get('http://www.baidu.com', (res1) = {var body = new Buffer(' ');
        res1.on('data', (chunk) = { 
            body = Buffer.concat([body, chunk]);
         });
        res1.on('end', () = { body = Buffer.from(body); // Copy the header informationfor(let i inres1.headers){ res.setHeader(i, res1.headers[i]); } // Return the content, the agent succeeded res.write(body); res.end(); }); }) }).listen(8000);Copy the code

Proxy is so simple, of course, this is just a principle, a way to implement, is to grab the web page and print to the page.

Then, I found an amazing way of writing HTTP in Node (maybe I have a little knowledge). A method that uses HTTP method as CONNECT method, puts the current link in the link state, that is, will not break, and then uses net.connect method to link to the request link. The establishment of mutual reading and writing channels.

const http=require("http")
const net=require("net")
const url=require("url")
const proxy = http.createServer((req, res) = {
    const options = {
        port: 1337,
        host: 'localhost',
        method: 'CONNECT'/ / triggers"connect" https://nodejs.org/api/http.html#http_event_connect
        path: 'www.baidu.com:80'
    };
    const req1 = http.request(options);
    req1.end();
    req1.on('connect', (res1, socket, head) = {
        let context=new Buffer("")
        // make a request over an HTTP tunnel
        socket.write('GET/HTTP / 1.1 \ r \ n' +
                    'Host: www.baidu.com:80\r\n' +
                    'Connection: close\r\n' +
                    '\r\n');
        socket.on('data', (chunk) = {
            context = Buffer.concat([context, chunk]);
        });
        socket.on('end', () =  {for(let i in req.headers){
                res.setHeader(i, req.headers[i]);
            }
            context=context.toString().split("\n\r\n")
            context.shift()
            res.end(context.join(""))}); }); }).listen(1337); proxy.on('connect', (req, cltSocket, head) = {
    const srvUrl = url.parse(`http://${req.url}`);
    const srvSocket = net.connect(srvUrl.port, srvUrl.hostname)
    cltSocket.write('the HTTP / 1.1 200 Connection Established \ r \ n' +
    'Proxy-agent: Node.js-Proxy\r\n' +
    '\r\n'); srvSocket.write(head); Srvsocket.pipe (cltSocket).pipe(srvSocket)});Copy the code

The simplicity of this method is that when you access the HTTP server, the HTTP server invokes a link to itself, sets method to CONNECT, and creates a clientSocket. The HTTP server also listens for connect events and fires the HTTP Server's connect when method is connected. Once the link is through, the HTTP Server creates a net link to the site that needs the proxy, returns a serverSocket, and the serverSocket reads the content and writes to clientSocket. ClientSocket in turn tells serverSocket that the write succeeded until the proxy succeeds.

Unpacking webPack practices (three approaches)

optimization.splitChunks

True unpack, refer to the link

module.exports = { //... optimization: { splitChunks: { // ... MinChunks: 2,// This property sets the number of times the current module appears in different modules. If there are two references, the module will be re-packaged. / /... }}};Copy the code

Externals removes unnecessary dependency packages

Just note the root problem. Root is the equivalent of window on the Web, so it's window.react, not to mention prop-type.

externals:{
    react:{ 
       root: 'React',
       amd: 'react',
       commonjs: 'react',
       commonjs2: 'react' 
    },
    "prop-types":{ 
      root: 'PropTypes',
      amd: 'prop-types',
      commonjs: 'prop-types',
      commonjs2: 'prop-types'}}Copy the code

DLL and External

Exteranl is to remove other people's bags.

DLL is to create your own tool library.

const library = '[name]_lib'
module.exports = {
  mode:"production",
  entry: {
    vendors: ['react'.'react-dom']
  },
  output: {
    filename: '[name].dll.js',
    path: path.join(__dirname,"dist/vendor"),
    //libraryTarget: "umd",
    library
  },
  plugins: [
    new webpack.DefinePlugin({ 
      'process.env'NODE_ENV: json.stringify ({// for packing things in react NODE_ENV: json.stringify ("production")
      } 
    }),
    new webpack.DllPlugin({
      path: path.join(__dirname, 'dist/[name]-manifest.json'),
      // This must match the output.library option above
      name: library
    }),
  ]
}
Copy the code

Dynamic link libraries are used in production; do not configure external here.

new webpack.DllReferencePlugin({
    context: __dirname,
    manifest: path.join(__dirname, 'dist/vendors-manifest.json'})),Copy the code

My blog is synchronized to tencent cloud + community, invite everyone to come together: cloud.tencent.com/developer/s...

Search
About
mo4tech.com (Moment For Technology) is a global community with thousands techies from across the global hang out!Passionate technologists, be it gadget freaks, tech enthusiasts, coders, technopreneurs, or CIOs, you would find them all here.