模块热替换(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"] ] }