如何利用 Babel 优化项目

Babel优化项目的方向主要包括以下两点:

  • 减少项目文件体积
  • 设置访问公共函数,避免创建重复函数方法(也是间接减少体积)

测试环境搭建

本次,我们基于webpack,搭建测试 demo。

// 初始化项目
npm init -y

// 添加webpack
npm install webpack webpack-cli --save-dev

// 添加babel相关,进行js代码转换
npm install -D babel-loader @babel/core @babel/preset-env

// 生成html文件
npm install -D html-webpack-plugin

创建webpack.config.js文件

const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');

module.exports = {
  mode: 'production',
  entry: {main: ['./src/index.js']},
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
    clean: true
  },
  module: {
    rules: [
      {
        test: /\.m?js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env'],
          }
        }
      }
    ]
  },
  plugins: [new HtmlWebpackPlugin()],
};

创建index.htmlindex.jsutil.js文件

// util.js
async function requestUtil() {
  await 0;
}
export { requestUtil }

// index.js
require('./util');

添加package.json

"webpack": "npx webpack --config webpack.config.js"

执行打包命令:yarn webpack

打包后的文件为1.09k

引入Polyfill

为了向后兼容浏览器,需要添加Polyfill

从 Babel 7.4.0 开始,该包已被弃用,取而代之的是直接包含 core-js/stable(用于填充 ECMAScript 功能)和 regenerator-runtime/runtime(需要使用转译的生成器函数)

因为已经被废弃了,所以不需要再单独安装@babel/polyfill,直接在项目中使用core-js/stableregenerator-runtime/runtime即可。

index.js中直接引入。

import "core-js/stable";
import "regenerator-runtime/runtime";

require('./util');

执行打包命令:yarn webpack

打包后的文件为158k

减少项目文件体积

问题:比较上次两次打包的大小:1.09k -> 158k。由于添加了浏览器兼容的代码,导致项目体积增大。

添加浏览器兼容代码导致项目增大无可厚非,但是打包后的项目中包含了大量无效的代码。

因为我们添加的兼容代码是全量添加的,就是我们项目中只用到了很少一部分的语法兼容代码。但是最后打包时,却把所有语法的兼容代码打入到项目中,出现了很多无效的代码。该如何处理?

那我们就按需加载,就是我们用到了哪个语法,就加入哪个语法的兼容的代码。在"@babel/preset-env"中,添加属性"useBuiltIns": "usage"即可,同时需要安装core-js@3

npm install core-js@3 --save
// webpack.config.js
...
module: {
    rules: [
      {
        test: /\.m?js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [['@babel/preset-env', {
              // 按需加载
                useBuiltIns: 'usage',
                corejs: 3,
            }]],
          }
        }
      }
    ]
  },
...

因为要按需加载,所以要去除index.js中的core-js/stableregenerator-runtime/runtime

// import "core-js/stable";
// import "regenerator-runtime/runtime";
require('./util');

执行打包命令:yarn webpack

打包后的文件为158k -> 30.3k。比较两次包体积,可以看出按需加载有效。

防止重复函数创建

使用插件@babel/plugin-transform-runtime, 可以重用 Babel 的注入帮助代码以节省代码大小。

安装插件

npm install --save-dev @babel/plugin-transform-runtime

npm install --save @babel/runtime // 需要配合添加
// webpack.config.js
     ...
     options: {
       presets: [['@babel/preset-env', {
          // 按需加载
          useBuiltIns: 'usage',
          corejs: 3,
        }]],
       // 避免公共函数重复创建;避免造成作用域污染
       plugins: ["@babel/plugin-transform-runtime"]
   }
    ...

执行打包命令:yarn webpack 打包后的文件为30.3k -> 7.53。比较两次包体积,可以看出防重复有效

这个插件,除了能够减少项目体积,也能防止作用域污染。这在写一个包项目时特别有用。