一个将指定路径替换成nodeModules中路径的babel插件

129 阅读1分钟

源代码:

import { connect } from '@/lib/commonModule';

转换后:

import { connect } from "react-redux";

背景:

使用Taro开发,公司小程序框架必须要求第三方包提前打包,导致H5导入node_modules中代码必须写成import { connect } from '@/lib/commonModule';形式。

解决方法:

若H5也在build之前,提前将第三方打包的话,这样就无法支持treeshaking。所以解决方法就是通过tsconfig配置,将@/lib/commonModule映射到一个从node_modules导出的文件。

// tsconfig配置
{
    "paths": {
        "@/lib/commonModule": ["./commonModule.ts"],
    },
}
// commonModule.ts文件内容
export { connect } from "react-redux";

这样实际导出的文件就是从node_modules中获取,从而支持treeshaking了。

但这样存在一个问题,就是会将commonModule中reexport的第三方npm包全部打包进app文件中,导致首屏加载的app文件过大。而解决这个问题的方法,就是如文章开头所示,在编译阶段,通过babel插件,将'@/lib/commonModule'路径直接替换为node_modules中的路径。

思路:

babel插件配置如下:

[    replacePathPlugin,    {            includes: ['src'],
            package: ['@/lib/commonModule'],// 支持数组
            modulePath: path.resolve(__dirname, './commonModule.ts'),
    },
],

通过分析modulePath,也就是reexport第三方npm包的文件,生成一个template模板,用于下一步的替换。

模板如下:

{
  connect: {
		source: 'react-redux',
		importKind: 'value',
		specifiers: {
			type: 'ImportSpecifier',
			imported: 'connect',
			local: 'connect',
		},
	}
}

下一步就是使用babel将业务代码中的@/lib/commonModule替换为react-redux了。

源码稍后补上。