处理高级语法
es6
插件
- babel-loader:
使用 Babel 和 webpack 转译 ES6 到 ES5
- @babel/core
babel核心模块,调用transform转化方法实现转化
- @babel/preset-env
转化目标模块(即ES5模块)
安装插件
$ yarn add babel-loader @babel/core @babel/preset-env -D
webpack配置
module.rules添加babel-loader配置
module: {
rules: [
{
test: /\.js$/i,
use: {
{
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
{
"targets": {
"browsers": "last 2 versions"
},
"loose": true,
"modules": "commonjs",
"useBuiltIns": false
}
],
plugins: []
},
},
},
include: path.resolve(__dirname, 'src'),
exclude: /(node_modules|bower_components)/,
}
],
}
然后 yarn build 打包,你会发现项目中的ES6语法全部被转化成了ES5语法
ES7装饰器 & Class语法解析
插件
- @babel/plugin-proposal-decorators
- @babel/plugin-proposal-class-properties
安装插件
$ yarn add @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators -D
webpack配置
plugins 中添加插件:
module: {
rules: [
{
test: /\.js$/i,
use: {
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
plugins: [
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties", { "loose" : true }]
]
},
},
},
include: path.resolve(__dirname, 'src'),
exclude: /(node_modules|bower_components)/,
}
],
}
也可以把 babel 配置单独配置到.babelrc文件中:
{
"presets": [
"@babel/preset-env",
{
"targets": {
"browsers": "last 2 versions"
},
"loose": true,
"modules": "commonjs",
"useBuiltIns": false
}
],
"plugins": [
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
],
[
"@babel/plugin-proposal-class-properties",
{
"loose": true
}
]
]
}
@babel/plugin-transform-runtime
babel在处理类似于Array的includes,from等高阶语法时,需要polyfill解析编译
使用@babel/plugin-transform-runtime插件的理由:
- @babel/preset-env设置useBuiltIns:"entry"时,需要手动引入polyfill,设置useBuiltIns:"usage"时,polyfill作为全局对象引入,容易造成全局变量污染。@babel/plugin-transform-runtime可以对polyfill做到按需引入。
- babel在编译js时会使用很多辅助代码。如_extend,@babel/plugin-transform-runtime可以把这些辅助代码进行抽离,缩小文件大小
@babel/plugin-transform-runtime配置:
//.babelrc
{
"presets": [
"@babel/preset-env",
{
"targets": {
"browsers": "last 2 versions"
},
"loose": true,
"modules": "commonjs",
"useBuiltIns": false
}
],
"plugins": [
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
],
[
"@babel/plugin-proposal-class-properties",
{
"loose": true
}
],
[
"@babel/plugin-transform-runtime",
{
"corejs": 3,
"helpers": true
}
]
]
}
编译React
安装babel react解析
$ yarn add @babel/preset-react
然后babel配置中添加react相关配置
//.babelrc
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"browsers": "last 2 versions"
},
"loose": true,
"modules": "commonjs",
"useBuiltIns": false
}
],
"@babel/preset-react"
],
"plugins": [
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
],
[
"@babel/plugin-proposal-class-properties",
{
"loose": true
}
],
[
"@babel/plugin-transform-runtime",
{
"corejs": 3,
"helpers": true
}
]
]
}
编译TypeScript
安装babel typescript解析
$ yarn add @babel/preset-typescript -D
然后在babel添加typescript解析配置
//.babelrc
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"browsers": "last 2 versions"
},
"loose": true,
"modules": "commonjs",
"useBuiltIns": false
}
],
"@babel/preset-react",
"@babel/preset-typescript"
],
"plugins": [
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
],
[
"@babel/plugin-proposal-class-properties",
{
"loose": true
}
],
[
"@babel/plugin-transform-runtime",
{
"corejs": 3,
"helpers": true
}
]
]
}
babel7以下版本可以选择typescript+ts-loader/awesome-typescript-loader方案
处理全局变量
expose-loader
允许暴露一个模块(整体或者部分)给全局对象(self、window 和 global)
$ yarn add expose-loader -D
下面以jquery为例,内联用法:
import $ from "expose-loader?exposes=$,jQuery!jquery";
// 将 `jquery` 添加到全局对象中,其名称为 `$` 和 `jQuery`,多个名称之间用“,”隔开
//此时就可以使用window.$和window.jQuery
也可以写到webpack配置中:
module.exports = {
module: {
rules: [
{
test: require.resolve("jquery"),
loader: "expose-loader",
options: {
exposes: ["$", "jQuery"],
},
},
{
test: require.resolve("underscore"),
loader: "expose-loader",
options: {
exposes: [
"_.map|map",
{
globalName: "_.reduce",
moduleLocalName: "reduce",
},
{
globalName: ["_", "filter"],
moduleLocalName: "filter",
},
],
},
},
],
},
};
webpack.ProvidePlugin
自动向各模块注入内容,我们还是以jquery为例:
const webpack = require('webpack')
module.exports = {
plugins: [
new webpack.ProvidePlugin({
$: 'jquery'
})
]
}
此时webpack打包的时候,会往各模块自定注入“$”作为jquery的别名
webpack不打包第三方cdn引入模块
有时候我们在html中通过script引入的第三方cdn包,不希望被webpack打包,可以通过配置externals(从输出的 bundle 中排除依赖)实现
//index.html
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
//webpack.config.js
module.exports = {
//...
externals: {
jquery: 'jQuery',
},
};
//js中依然可以这样使用
import $ from 'jquery';
$('.my-element').animate(/* ... */);