什么是装饰器语法?

装饰器(新特性未定案)

背景

之前我们讲过可以通过 @preset-env 和 core-js 转化高级的 api,但是这边注意的是这种方法他不支持提案中的语法(stage-x),例如装饰器语法,如下:

  1. /** ./src/index.js **/
  2. @d
  3. class Animal {
  4. constructor(type){
  5. this.type = type;
  6. }
  7. static a = 10;
  8. state = {
  9. a: 1
  10. }
  11. getType(){
  12. return this.type;
  13. }
  14. }
  15. function d(target){
  16. console.log(target)
  17. }
  18. let animal = new Animal('哺乳类');
  19. console.log(animal.type);
  20. console.log(Animal.a);
  21. console.log(animal.state)

yarn build 运行,结果如下:
image.png
打包失败,提示 decorators-legacy 语法不支持。

解决方案

安装 plugins

  1. 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'
        })
    ]
}

打包结果

image.png
image.png