如何通过Webpack导入JS库中未实例化的函数并完成打包?
问题描述
我正在创建一个JavaScript库,供同一目录下的多个项目使用,目录结构如下:
- JSlib - function1.js - function2.js - function3.js - projects - project1 - public - bundle.js - src - main.js (导入function1、function2) webpack.config - project2 - public - bundle.js - src - main.js (导入function3) - webpack.config
理想中main.js是作为配置文件,指定当前项目需要的JS文件,内容类似:
import { func1 } from '../JSlib/function1.js' import { func2 } from '../JSlib/function2.js' import { func3 } from '../JSlib/function3.js' // ...
但用Webpack打包时遇到问题:我需要仅导入函数但不立即执行它们,比如这个仅作定义供组件调用的函数:
export function toggleSlideover() { document .getElementById("slideover-container") .classList.toggle("invisible"); document.getElementById("slideover-bg").classList.toggle("opacity-0"); document.getElementById("slideover-bg").classList.toggle("opacity-25"); document.getElementById("slideover").classList.toggle("-translate-y-full"); }
如果只是导入这个函数但不"使用"它,Webpack会把它从打包结果中移除。试过冗余定义:
import { toggleSlideover as tsl } from "../../../../jslib/mobileNav.js"; function toggleSlideover() { tsl(); }
但工具提示函数未被使用;直接导入不调用的话不会被打包,导入后立即调用又会执行函数,这不是我想要的。
解决方案
1. 禁用Tree Shaking
Webpack默认在生产模式下开启Tree Shaking,会移除未被引用的代码。可以在Webpack配置中关闭相关逻辑:
// webpack.config.js module.exports = { optimization: { usedExports: false } };
如果生产模式下Terser插件仍会移除未使用代码,需额外配置:
const TerserPlugin = require('terser-webpack-plugin'); module.exports = { optimization: { minimizer: [ new TerserPlugin({ terserOptions: { compress: { unused: false // 禁用未使用代码移除逻辑 } } }) ] } };
2. 将函数挂载到全局对象
把导入的函数挂载到window上,让Webpack识别到函数被使用,同时保留供外部调用的能力:
// main.js import { toggleSlideover } from '../../../../jslib/mobileNav.js'; // 挂载到全局环境 window.toggleSlideover = toggleSlideover;
这样既不会立即执行函数,Webpack也会将其打包进bundle,后续可通过toggleSlideover()调用。
3. 用sideEffects标记库文件
在JSlib目录下创建package.json,标记所有JS文件存在副作用,阻止Webpack进行Tree Shaking:
// JSlib/package.json { "sideEffects": ["*.js"] }
Webpack识别到该配置后,会保留所有导入的库文件内容。
4. 导出函数集合对象
在JSlib中创建汇总入口文件,将所有函数整合到一个对象导出:
// JSlib/index.js import { func1 } from './function1.js'; import { func2 } from './function2.js'; import { toggleSlideover } from './mobileNav.js'; export const MyLib = { func1, func2, toggleSlideover };
在项目main.js中导入该对象,可选择挂载到全局:
import { MyLib } from '../../JSlib/index.js'; window.MyLib = MyLib;
Webpack会因为对象被引用而保留所有内部函数,后续通过MyLib.toggleSlideover()调用即可。
内容的提问来源于stack exchange,提问作者Mojoio
相关产品推荐
相关产品推荐

