基于Preact+Rollup+TypeScript构建CDN依赖组件库的方案咨询
需求概述
我正在尝试结合Preact、Rollup与TypeScript,打造一个所有依赖均通过CDN引入的组件库。期望将如下product.tsx文件:
import { FunctionalComponent } from 'preact'; import register from 'preact-custom-element'; interface ProductProps { name: string; } const Product: FunctionalComponent<ProductProps> = ({name}: ProductProps) => <p>Hello {name}</p>; register(Product, 'x-product', ['name'], { shadow: false });
通过TypeScript打包工具生成类似如下的product.js文件(可进一步压缩):
(function() { 'use strict'; const Product = ({ name }) => preact_10_19_3.h("p", null, "Hello ", name); preact-custom-element_4_3_0.register(Product, 'x-product', ['name'], { shadow: false }); })();
该文件可在已通过CDN加载依赖并设置别名(避免版本冲突)的index.html中使用:
<body> <!-- Load from CDN --> <script src="cdn/10.19.3/preact.min.js"></script> <!-- Alias --> <script> window.preact_10_19_3 = preact; </script> <!-- Register x-product webcomponent --> <script src="./product.js"></script> <!-- Use webcomponent --> <x-product name="Test" /> </body>
请问如何实现这一需求?我发现Rollup的iife格式配置有潜力,但相关文档不足,是否应改用Webpack?这种CDN引入带来的加载性能提升是否值得?
实现方案(基于Rollup + TypeScript)
1. 安装必要依赖
首先安装Rollup及相关工具插件:
npm install --save-dev rollup @rollup/plugin-typescript @rollup/plugin-node-resolve rollup-plugin-terser typescript @types/preact @types/preact-custom-element
2. 配置Rollup
创建rollup.config.js文件,核心是标记外部依赖并映射到全局别名:
import typescript from '@rollup/plugin-typescript'; import { terser } from 'rollup-plugin-terser'; export default { input: 'src/product.tsx', // 你的源文件路径 output: { file: 'dist/product.js', // 输出文件路径 format: 'iife', // 生成自执行函数格式 globals: { 'preact': 'preact_10_19_3', // 映射Preact到全局变量 'preact-custom-element': 'preact-custom-element_4_3_0' // 映射自定义元素工具到全局变量 }, strict: true // 启用严格模式 }, external: ['preact', 'preact-custom-element'], // 标记这两个包为外部依赖,不打包进产物 plugins: [ typescript(), // 处理TypeScript与TSX语法 terser() // 可选,压缩产物代码 ] };
3. 配置TypeScript
创建tsconfig.json适配Preact的JSX语法:
{ "compilerOptions": { "jsx": "react-jsx", // 使用新JSX转换 "jsxImportSource": "preact", // 指定JSX源为Preact "module": "ESNext", // 符合Rollup的模块要求 "target": "ES2015", // 兼容现代浏览器 "strict": true, // 启用严格类型检查 "moduleResolution": "bundler" // 使用打包器的模块解析逻辑 }, "include": ["src/**/*"] // 包含源文件目录 }
4. 执行编译
在package.json中添加编译脚本:
{ "scripts": { "build": "rollup -c" } }
运行npm run build即可生成目标产物。
Rollup vs Webpack:无需切换
完全不需要改用Webpack,Rollup更适合库打包场景:
- Rollup配置更简洁,针对ES模块的打包优化更彻底,产物体积更小
- IIFE格式是Rollup的核心能力之一,通过
external和globals就能轻松实现外部依赖的全局变量映射 - 相关文档足够覆盖你的需求,核心就是掌握外部依赖标记和全局变量映射两个配置项
Webpack虽能实现相同效果,但配置复杂度更高,且针对应用打包做了更多冗余优化,对于库场景来说没必要。
CDN引入的性能价值:非常值得
这种方案的性能提升是实实在在的,核心优势包括:
- 大幅缩减产物体积:组件库只打包业务代码,依赖由CDN提供,产物大小可能仅几KB
- 缓存复用:用户若访问过其他使用相同版本Preact的站点,CDN缓存会直接命中,无需重复下载依赖
- 并行加载:CDN资源与组件脚本可并行加载,提升页面加载速度
- 版本隔离:通过别名机制避免依赖版本冲突,多个组件库可在同一页面共存
内容的提问来源于stack exchange,提问作者Gábor Ábrahám
相关产品推荐
相关产品推荐

