babel-plugin-import
一、认识
babel-plugin-import
二、通过 babel-plugin-import 按需引入 lodash
2.1 准备
-
安装
lodash
、babel-loader
、@babel/core
、babel-plugin-import
依赖yarn add babel-loader @babel/core babel-plugin-import -D
yarn add lodash -S
2.2 常规引入 lodash
-
webpack.config.js
配置如下 (不使用任何 loader):const Path = require('path');
module.exports = {
mode: "development",
entry: Path.resolve(process.cwd(), "./src/index.js"),
output: {
filename: "index.js",
path: Path.resolve(process.cwd(), "./build/"),
},
}; -
入口文件引入
lodash
import { flatten, concat } from "lodash";
console.log(flatten, concat); -
执行
webapck build
进行打包编译,编译结果如图所示:Preview如图所示: 只有两句话而已,但是打包出的文件体积巨大。因为他把真个 lodash 文件都打包了,所以我们需要按需引入,减小打包文件的体积
2.3 按需引入 lodash -- babel.config.js
-
webpack.config.js
配置babel-loader
如下:{
test: /\.js$/,
use: {
loader: "babel-loader",
},
}, -
webpack.config.js
完整配置如下:const Path = require("path");
module.exports = {
mode: "development",
entry: Path.resolve(process.cwd(), "./src/index.js"),
output: {
filename: "index.js",
path: Path.resolve(process.cwd(), "./build/"),
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: "babel-loader",
},
},
],
},
}; -
babel.config.js
配置如下:module.exports = {
plugins: [
[
"import",
{
libraryName: "lodash",
libraryDirectory: "",
},
],
],
}; -
入口文件引入
lodash
import { flatten, concat } from "lodash";
console.log(flatten, concat); -
执行
webapck build
进行打包编译,编译结果如图所示:Preview如图所示: 打包出来的文件体积一下子变得小了许多
2.4 按需引入 lodash -- webpack.config.js
-
webpack.config.js
配置babel-loader
如下:{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
plugins: [
[
"import", {
libraryName: "lodash",
libraryDirectory: "",
},
],
],
},
},
} -
webpack.config.js
完整代码如下:const Path = require('path');
module.exports = {
mode: "development",
entry: Path.resolve(process.cwd(), "./src/index.js"),
output: {
filename: "index.js",
path: Path.resolve(process.cwd(), "./build/"),
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
plugins: [
[
"import", {
libraryName: "lodash",
libraryDirectory: "",
},
],
],
},
},
},
],
},
}; -
入口文件引入
lodash
import { flatten, concat } from "lodash";
console.log(flatten, concat); -
执行
webapck build
进行打包编译,编译结果如图所示:Preview如图所示: 打包出来的文件体积一下子变得小了许多
三、通过指定路径引入所需 lodash 模块来实现按需引入
-
webapck.config.js
配置如下(关闭所有 loader):const Path = require("path");
module.exports = {
mode: "development",
entry: Path.resolve(process.cwd(), "./src/index.js"),
output: {
filename: "index.js",
path: Path.resolve(process.cwd(), "./build/"),
},
module: {
rules: [
],
},
}; -
入口文件分别指定路径引入所需模块
// import { flatten, concat } from "lodash";
import flatten from 'lodash/flatten';
import concat from 'lodash/concat';
console.log(flatten, concat); -
执行
webapck build
进行打包编译,编译结果如图所示:Preview如图所示: 打包出来的文件体积跟
babel-plugin-import
效果是一样的。
四、通过自己实现的 babel-plugin-import 按需引入 lodash
通过指定路径引入所需 lodash 模块来实现按需引入的引入模块方案,我们可以知道所谓的按需引入,就是将import {flatten,concat} from "lodash"
转换为 import flatten from "lodash/flatten"
和 import concat from "lodash/concat"
4.1 不同引入模块方式的 AST 对比
import {flatten,concat} from "lodash"
AST 结构:
import flatten from "lodash/flatten"
import concat from "lodash/concat"
AST 结构:
4.2 实现
-
根目录/plugins/babel-plugin-import.js
编写插件const BabelCore = require("@babel/core");
const Types = require("babel-types");
const babelPluginImport = {
visitor: {
ImportDeclaration: {
enter(nodePath, state = { }) {
const { specifiers, source } = nodePath.node;
if (
state.opts.libraryName === "lodash"
&& !Types.isImportDefaultSpecifier(specifiers[0])
) {
const importDeclarations = specifiers.map((specifier) => Types.importDeclaration(
[Types.importDefaultSpecifier(specifier.local)],
Types.stringLiteral(`${source.value}/${specifier.local.name}`),
));
nodePath.replaceWithMultiple(importDeclarations);
}
},
},
},
};
module.exports = function () {
return babelPluginImport;
}; -
webpack.config.js
中配置babel-loader
,使用自定义插件const Path = require("path");
module.exports = {
mode: "development",
devtool: false,
entry: Path.resolve(process.cwd(), "./src/index.js"),
output: {
filename: "index.js",
path: Path.resolve(process.cwd(), "./build/"),
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: "babel-loader",
options: {
plugins: [
[
Path.resolve(process.cwd(), './plugins/babel-plugin-import.js'),
{
libraryName: 'lodash',
},
],
],
},
},
},
],
},
}; -
执行
webapck build
进行打包编译,编译结果如图所示:Preview如图所示: 打包出来的文件体积跟
babel-plugin-import
效果是一样的。