Skip to content

weback编译JS

目的:将ES6+转成ES5,从而保证,JS在低版本浏览器的兼容性

解决方案

一、babel/preset-env(一些高级语法无法转换如promise)

先简单认识一下babel

我们将下面ES6代码转译ES5

安装依赖

js
yarn add babel-loader @babel/core @babel/preset-env

webpack.config.js

js
const { resolve } = require('path');

const MiniCssEctractPlugin = require('mini-css-extract-plugin');

const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
  mode:'development',

  entry: './src/index.js',

  output: {
      path: resolve(__dirname, 'dist'),
      filename: 'bundle.js'
  },
  module:{
      rules:[
          {
              test: /\.css$/i,
              use:[MiniCssEctractPlugin.loader,'css-loader']
          },{
              test: /\.m?js$/,
              exclude: /node_modules/,
              use: {
                loader: 'babel-loader',
                options: {
                  presets: [
                    ['@babel/preset-env', { targets: "defaults" }]
                  ]
                }
              }
            }
      ]
  },
  plugins:[
      new MiniCssEctractPlugin({
          filename:'css/[name].css'
      }),
      new HtmlWebpackPlugin({
          template:'src/index.html'
      })
  ]

}

输出

可以发现,一些基本的ES6转换可以的,但是Promise之类的就不可以,查看源码发现promise没有转译,用ie打开报错。

二、babel/polyfill(转译所有js新语法)

js
yarn add @babel/polyfill -D
import '@babel/polyfill' // 从入口文件中引入

这个时候我们再去看源码时候,就已经被转译成ES5啦。再次用ie打开发现还是不行。问题出在哪里呢?还需要添加构建目标环境(target)

js
// webpack.conf.js
module.export = {
    // ...
    target: ["web", "es5"]
}

但是我们发现有另外的问题,打包后的代码体积变得很大,因为它会把ES6、ES6+的代码都转为ES5。

三、core-js(按需转译JS新语法)

需要将之前引入的polyfill注释掉

js
yarn add core-js -D

配置:

js
按需加载:useBuildIns:'usage'
指定版本:corejs:3
js
const { resolve } = require('path');

const MiniCssEctractPlugin = require('mini-css-extract-plugin');

const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    mode:'development',

    entry: './src/index.js',

    output: {
        path: resolve(__dirname, 'dist'),
        filename: 'mian.js'
    },
    module:{
        rules:[
            {
                test: /\.css$/i,
                use:[MiniCssEctractPlugin.loader,'css-loader']
            },{
                test: /\.m?js$/,
                exclude: /node_modules/,
                use: {
                  loader: 'babel-loader',
                  options: {
                    presets: [
                      ['@babel/preset-env', 
                    {
                        useBuiltIns: 'usage',

                        corejs: 3,

                        targets: {
                            chrome: '58',
                            ie: '9',
                            firefox: '60',
                            safari: '10',
                            edge: '17'
                        }
                    }]
                    ]
                  }
                }
              }
        ]
    },
    plugins:[
        new MiniCssEctractPlugin({
            filename:'css/[name].css'
        }),
        new HtmlWebpackPlugin({
            template:'src/index.html'
        })
    ],
    target:["web","es5"]

}

然后再来看体积大小,小了不少。