如何在自定义Angular 15库中打包CKEditor v4.22.1相关文件
环境与现状
用Angular 15开发一个Angular库,基于ckeditor4-angular v4.0.1封装了CKEditor v4.22.1的组件my_component,供其他Angular应用调用。当前项目结构如下:
my_project -> projects -> my_library -> my_module -> assets -> ckeditor -> my_component -> my_component.ts my_component.html -> my_module.module.ts -> index.ts -> ng-package.json -> public-api.ts -> src -> assets -> ckeditor
组件模板my_component.html里的路径写死为根目录资产:
<ckeditor type="classic" editorUrl="/assets/ckeditor/ckeditor.js" config="/assets/ckeditor/config.js" [id]="uniqueId" [formControlName]="uniqueId" ></ckeditor>
目前CKEditor相关文件(ckeditor.json、config.js、plugins/等)都存在根项目的src/assets/ckeditor,使用组件的项目需要手动复制这些文件,操作繁琐。希望将文件迁移至库的my_module/assets/ckeditor,构建库时自动打包这些资产,其他项目导入模块即可直接使用,同时要求打包时压缩CKEditor的JS文件。
解决步骤
1. 迁移CKEditor文件
直接将my_project/src/assets/ckeditor下的所有文件(包括子文件夹),全部移动到my_project/projects/my_library/my_module/assets/ckeditor目录。
2. 调整组件模板路径
原绝对路径/assets/...无法适配库的打包结构,需修改为适配路径,两种可选方式:
- 简单方案:使用相对路径
<ckeditor type="classic" editorUrl="./assets/ckeditor/ckeditor.js" config="./assets/ckeditor/config.js" [id]="uniqueId" [formControlName]="uniqueId" ></ckeditor> - 稳妥方案:动态生成路径(避免部署路径差异问题)
在my_component.ts中添加路径获取逻辑:
模板中绑定动态路径:import { Component } from '@angular/core'; @Component({ selector: 'app-my-component', templateUrl: './my_component.html' }) export class MyComponent { uniqueId = 'editor-' + Math.random().toString(36).slice(2); get ckeditorAssetsPath(): string { return `${document.baseURI}assets/my_library/my_module/assets/ckeditor/`; } }<ckeditor type="classic" [editorUrl]="ckeditorAssetsPath + 'ckeditor.js'" [config]="ckeditorAssetsPath + 'config.js'" [id]="uniqueId" [formControlName]="uniqueId" ></ckeditor>
3. 配置ng-packagr打包资产
修改my_project/projects/my_library/my_module/ng-package.json,添加资产打包配置,告诉打包工具包含CKEditor文件:
{ "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", "dest": "../../../dist/my_library/my_module", "lib": { "entryFile": "public-api.ts" }, "assets": [ { "input": "./assets/ckeditor", "output": "./assets/ckeditor" } ] }
执行ng build时,工具会自动将my_module/assets/ckeditor下的文件复制到打包后的dist/my_library/my_module/assets/ckeditor目录。
4. 压缩CKEditor JS文件
使用terser工具实现JS文件压缩,步骤如下:
- 安装依赖:
npm install terser --save-dev - 编写批量压缩脚本(项目根目录新建
compress-ckeditor.js):const fs = require('fs'); const path = require('path'); const terser = require('terser'); const ckeditorDistDir = path.join(__dirname, 'dist/my_library/my_module/assets/ckeditor'); // 压缩单个JS文件 function compressJsFile(filePath) { const content = fs.readFileSync(filePath, 'utf8'); terser.minify(content, { compress: true, mangle: true }) .then(result => { fs.writeFileSync(filePath, result.code); console.log(`已压缩:${filePath}`); }) .catch(err => console.error(`压缩失败 ${filePath}:`, err)); } // 压缩主文件 compressJsFile(path.join(ckeditorDistDir, 'ckeditor.js')); compressJsFile(path.join(ckeditorDistDir, 'config.js')); // 遍历plugins目录压缩所有JS文件 function traversePluginsDir(dir) { const files = fs.readdirSync(dir); files.forEach(file => { const fullPath = path.join(dir, file); const stats = fs.statSync(fullPath); if (stats.isDirectory()) { traversePluginsDir(fullPath); } else if (file.endsWith('.js')) { compressJsFile(fullPath); } }); } traversePluginsDir(path.join(ckeditorDistDir, 'plugins')); - 在根项目
package.json中添加打包脚本:
后续执行"scripts": { "build:library": "ng build my_library && node compress-ckeditor.js" }npm run build:library即可完成库构建+CKEditor文件压缩。
5. 验证效果
运行打包脚本后,查看dist/my_library/my_module/assets/ckeditor目录,确认所有文件存在且JS文件体积已压缩。其他Angular应用安装该库后,直接导入my_module即可使用my_component,无需手动复制CKEditor文件。
内容的提问来源于stack exchange,提问作者Prabhu

