javascript - 优化汇总配置以启用摇树
问题描述
我想就如何构建一个方便使用和摇树优化的构建提供建议。我正在使用汇总来打包由多个组件组成的 UI 库。
我的架构是:
/src
/index.js
/components
/index.js
/component1
/index.js
/Comp.vue
...
/componentN
/index.js
/Comp.vue
/directives
/index.js
/directive1
/index.js
...
/directiveN
/index.js
src/components/index.js
看起来像
export { default as Comp1 } from './component1
...
export { default as CompN } from './componentN
src/directives/index.js
看起来像
export { default as Directive1 } from './directive1
...
export { default as DirectiveN } from './directiveN
每个内部index.js
只是为了方便的绑定,例如
import Comp from './Comp.vue'
export default Comp`
最后,src/index.js
将收集所有内容:
import { * as components } from './components'
import { * as directives } from './directives'
export { components, directives }
构建时,汇总配置如下所示:
{
input: 'src/index.js',
output: {
file: 'dist/lib.esm.js',
format: 'esm',
}
(当然我要避免所有的编译丑化插件,我认为它们会成为这个问题的噪音)
所以这个构建看起来不错,并且有效,但是......
- 使用起来非常不方便:
import { components } from 'lib'
const { Comp1 } = components
- 这种结构可能在使用时也破坏了树抖动,因为我们只在需要时才导入完整的
components
对象。Comp1
我知道我不应该是关心摇树的人,而是提供一个支持摇树的库,这就是它的意义所在。当使用最简单的@vue/cli 模板测试我的构建时,完整的库被导入,甚至@vue/cli 声称已经启用了开箱即用的 webpack-treeshaking 功能。
我不介意构建单独的文件而不是一个大的 esm 构建,但据我所知,一个带有摇树的文件构建是可能的。我担心构建单独的文件是CompA
内部需要CompB
,如果用户也需要CompB
,在这种情况下,它可能会在构建中重复(例如,一个外部使用版本和一个内部使用版本)。
我对如何进行优化一无所知。任何指针都受到高度欢迎。
解决方案
就目前而言,我能找到的唯一有效解决方案是在文件夹内的同一树结构中单独构建所有dist/
文件。我决定构建文件以提供 Vue 文件格式样式块,而无需最终消费者进一步构建或配置。
构建后看起来像这样:
/src
/index.js
/components
/index.js
/component1
/index.js
/Comp.vue
...
/componentN
/index.js
/Comp.vue
/directives
/index.js
/directive1
/index.js
...
/directiveN
/index.js
/dist
/index.js
/components
/index.js
/component1
/index.js
...
/componentN
/index.js
/directives
/index.js
/directive1
/index.js
...
/directiveN
/index.js
我创建了一个小的递归函数来查找所有“index.js”并将这个列表与汇总多入口点功能一起使用。希望汇总创建所有子文件夹,因此不需要检查或mkdir -p
.
// shorthand utility for 'find all files recursive matching regexp (polyfill for webpack's require.context)'
const walk = (directory, regexp) => {
let files = readdirSync(directory)
if (directory.includes('/examples'))
return []
return files.reduce((arr, file) => {
let path = `${directory}/${file}`
let info = statSync(path)
if (info.isDirectory())
return arr.concat(walk(path, regexp))
else if (regexp.test(file))
return arr.concat([path])
else
return arr
}, [])
}
// ...
const esm = walk(`${__dirname}/src`, /^index\.js$/)
.map(file => ({
input: file,
output: {
format: 'esm',
file: file.replace(`${__dirname}/src`, CONFIG.module)
},
...
}))
该过程的最后一部分是复制/粘贴package.json
到dist/
、cd
其中和npm publish
从中... 这已集成到我们的 CI 任务中,因为它与汇总或构建没有直接关系,而是与发布相关。
这并不完美,但由于缺乏输入,这是我发现的唯一方法。我希望它会帮助某人。
推荐阅读
- python - 检查numpy数组的形状
- sql - 更新 sqlserver
- java - 如何在 Spring Boot Thymleaf 模板的内联背景图像 css 标记中添加静态图像?
- asp.net-mvc - 结束响应后重定向到操作不起作用 vb.net mvc 5
- html - 如何将字段集的内容发送到电子邮件地址?
- regex - 在 python3 中使用正则表达式从文本中删除特定模式
- javascript - 尝试使用引用访问同级组件的 TextInput 时“未定义不是对象”
- mysql - MySQL 视图优化与子查询
- rust - 对 Actix 服务器中捕获的变量的引用会导致“参数要求它必须比‘静态’更有效”
- colors - 为颜色设置(实习生)变量