webpack四探-HMR、babel使用、打包react

模块热替换(Hot Module Replacement):

当我们使用webpackDevServer,修改内容的时候,会自动刷新页面。当我们需要在修改代码的时候不刷新页面,仅更新修改后的代码的时候,就可以使用HMR,需要在webpack.cnfig.js中:

const webpack=require('webpack');

devServer:{
    contentBase:'./dist',
    open:true,
    hot:true,           // 新增,在某些模块不支持热更新的时候会新刷新页面
    hotOnly:true        // 新增,即使在模块不支持热更新的时候也不会刷新页面,而是在控制台输出热更新失败
},
plugins:[
    new HtmlWebpackPlugin({template:'src/index.html'}),
    new CleanWebpackPlugin(),
    new webpack.HotModuleReplacementPlugin()        // 新增
],

babel:

npm install babel-loader @babel/core

module: {
  rules: [
    { test: /.js$/, exclude: /node_modules/, loader: "babel-loader" }
  ]
}

还需要安装和配置:

npm install @babel/preset-env --save-dev

{
    test: /.js$/,
    exclude: /node_modules/,
    loader: "babel-loader",
    options:{
        presets:['@babel/preset-env']
    }
}

还需要安装polyfill,因为有一些语法(如promise、map等不会被转换):

npm install --save @babel/polyfill

在业务代码顶部(如index.js):
import "@babel/polyfill";
这个时候会把所有ES6语法的转换都打包进main.js,所以文件会特别大,但是当我们只需要转换某些特性,如Promise的时候,就显得冗余,可以通过如下配置解决:

{
    test: /.js$/,
    exclude: /node_modules/,
    loader: "babel-loader",
    options:{
        presets:[['@babel/preset-env'],{
            useBuiltIns:'usage'
        }]
    }
}

这个意思是当我们做polyfill转换语法的时候,不是把所有特性都加进来,而是根据业务代码来决定到底要加什么
还可以加上其他配置,如:

presets:[[
    '@babel/preset-env',
    {
        useBuiltIns:'usage',
        targets:{
            // edge:'17',
            // firefox:'60',
            chrome:'>67',
            // safari:'11.2'
        }
    },
]]

它的意思是我们打包后的项目会运行在大于67版本的chrome浏览器下,这个时候babel需要判断是否需要做ES6到ES5的转换

当我们在开发类库、第三方模块或者组件库的时候用babel/polyfill会有问题,因为它会以全局变量的形式注入,会污染到全局环境,所以需要换一种打包方式:
npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime
还要修改配置:

{
    test: /.js$/,
    exclude: /node_modules/,
    loader: "babel-loader",
    options:{
        "plugins": [["@babel/plugin-transform-runtime",{
            "corejs": 2,
            "helpers": true,
            "regenerator": true,
            "useESModules": false
        }]]
    }
}

这个时候打包会报关于corejs的错,因为还需要安装:
npm install --save @babel/runtime-corejs2
plugin-transform-runtime会以闭包的形式去引入内容,不存在全局污染的问题,当然,在业务代码中只要使用polyfill就可以了。

babel的配置可能会很长,所以我们可以创建一个.babelrc文件,将相关配置项放到里面:

{
    "plugins": [["@babel/plugin-transform-runtime",{
        "corejs": 2,
        "helpers": true,
        "regenerator": true,
        "useESModules": false
    }]]
},

webpack.config.js中就不需要了:

{
    test: /.js$/,
    exclude: /node_modules/,
    loader: "babel-loader"
}

打包react:

npm install --save react react-dom
.babelrc中的内容为:

{
    "presets": [
        [
            "@babel/preset-env",
            {
                "useBuiltIns": "usage",
                "targets": {
                    "chrome": "67"
                }
            }
        ]
    ]
}

index.js中:

import "@babel/polyfill";
import React,{Component} from 'react';
import ReactDom from 'react-dom';

class App extends Component{
    render(){
        return <div>hello world</div>
    }
}

ReactDom.render(<App />,document.getElementById('root'));

这个时候打开页面会报错,因为直接用babel打包react框架代码时不行的,需要结合react的babel,需要安装:
npm install --save-dev @babel/preset-react
还需要对.babelrc进行配置:

{
    "presets": [
        [
            "@babel/preset-env",
            {
                "useBuiltIns": "usage",
                "targets": {
                    "chrome": "67"
                }
            }
        ],
        ["@babel/preset-react"]
    ]
}
原文地址:https://www.cnblogs.com/jingouli/p/12255740.html