什么是装饰器语法?
背景
之前我们讲过可以通过 @preset-env 和 core-js 转化高级的 api,但是这边注意的是这种方法他不支持提案中的语法(stage-x),例如装饰器语法,如下:
/** ./src/index.js **/
@d
class Animal {
constructor(type){
this.type = type;
}
static a = 10;
state = {
a: 1
}
getType(){
return this.type;
}
}
function d(target){
console.log(target)
}
let animal = new Animal('哺乳类');
console.log(animal.type);
console.log(Animal.a);
console.log(animal.state)
yarn build 运行,结果如下:
打包失败,提示 decorators-legacy 语法不支持。
解决方案
安装 plugins
yarn add @babel/plugin-proposal-decorators --dev
配置 webpack
看如下 46 行,只需要配置这一行,就可以打包 装饰器语法了。
/** ./webpack.config.js **/
let path = require('path');
let { CleanWebpackPlugin } = require('clean-webpack-plugin');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let MiniCssExtractPlugin = require('mini-css-extract-plugin');
let htmlPlugins = ['index'].map(chunkName => {
return new HtmlWebpackPlugin({
filename: `${chunkName}.html`,
inject: 'body',
chunks: [chunkName],
template: `./public/${chunkName}.html`
})
});
module.exports = {
devServer: {
port: 3000,
open: true,
compress: true,
static: './dist'
},
mode: 'development',
entry: {
index: './src/index.js'
},
output: {
filename: 'js/[name].[contenthash:8].js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/, // 忽略掉不要进行loader处理的文件
include: path.resolve(__dirname, './src'),
use: {
loader: 'babel-loader',
options: {
presets: [['@babel/preset-env', {
useBuiltIns: 'usage',
corejs: { version: 3 }
}]],
plugins: [
'@babel/plugin-transform-runtime',
['@babel/plugin-proposal-decorators', { "legacy": true }]],
}
}
},
{
test: /\.(htm|html)/,
use: 'html-withimg-loader',
},
{
test: /\.(ttf|woff|woff2|svg|eot)$/,
use: ['file-loader']
},
{
test: /\.(jpg|jpeg|png|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10240,
esModule: false
}
}
]
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, {
loader: 'css-loader',
options: {
modules: true
}
}, 'postcss-loader', 'sass-loader']
}
]
},
plugins: [
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: ['**/*']
}),
...htmlPlugins,
new MiniCssExtractPlugin({
filename: 'css/main.css'
})
]
}