从业务到框架:Elpis 企业级应用的 NPM 包抽离实践

在构建企业级前端框架 Elpis 的过程中,我们不仅关注功能的完整性与可扩展性,也致力于将其模块化、标准化,最终以 NPM 包的形式发布,供其他项目复用。本文将详细介绍如何将 Elpis 框架从业务代码中抽离,并封装为一个可发布的 NPM 包。


第一步:抽离业务代码

在框架开发初期,为了验证功能,我们嵌入了部分业务逻辑。要将 Elpis 独立成 NPM 包,首先需要将这些业务代码剥离,确保框架本身保持纯粹。

package.json 基本结构

json 复制代码
{
  "name": "elpis-core",
  "version": "1.0.0",
  "description": "企业级前端框架",
  "main": "index.js",
  "repository": {
    "type": "git",
    "url": "https://github.com/your-repo/elpis-core.git"
  },
  "author": "Your Name",
  "license": "ISC"
}

第二步:本地包调试

在正式发布前,我们使用 npm link 将 Elpis 框架软链到本地项目中,便于调试和验证抽离效果。

bash 复制代码
cd elpis-core
npm link
​
cd your-business-project
npm link elpis-core

第三步:核心模块抽离

Loader 路径配置

为了兼容业务项目与框架本身的资源加载,我们在 loader 中添加双路径支持:

ini 复制代码
const elpisPath = path.resolve(__dirname, '../../app/loader');
const businessPath = path.resolve(process.cwd(), './app/loader');

通过封装挂载逻辑,将两者统一加载。


第四步:Webpack 配置抽离与融合

我们将开发与生产环境的打包逻辑封装为统一接口:

ini 复制代码
function frontendBuild(env) {
  if (env === 'local') {
    FEBuildDev();
  } else if (env === 'production') {
    FEBuildProd();
  }
}

动态构建入口文件

使用 glob 动态读取 Elpis 与业务项目的页面入口:

ini 复制代码
const elpisEntryList = path.resolve(__dirname, '../../pages/**/entry.*.js');
const businessEntryList = path.resolve(process.cwd(), './app/pages/**/entry.*.js');

统一处理:

less 复制代码
function handlerFile(file, entries, htmlWebpackPluginList) {
  const entryName = path.basename(file, '.js');
  entries[entryName] = file;
  htmlWebpackPluginList.push(new HtmlWebpackPlugin({
    filename: path.resolve(process.cwd(), './app/public/dist', `${entryName}.tpl`),
    template: path.resolve(__dirname, '../../view/entry.tpl'),
    chunks: [entryName]
  }));
}

合并配置

ini 复制代码
let businessWebpackConfig = {};
try {
  businessWebpackConfig = require(`${process.cwd()}/app/webpack.config.js`);
} catch (e) {}
​
module.exports = merge.smart(defaultElpisWebpackConfig, businessWebpackConfig);

第五步:Loader 与别名配置

为避免解析错误,所有 loader 使用 require.resolve

css 复制代码
{
  test: /.vue$/,
  use: {
    loader: require.resolve('vue-loader')
  }
}

针对业务与框架 JS 文件分别处理:

css 复制代码
{
  test: /.js$/,
  include: [
    path.resolve(__dirname, '../../pages'),
    path.resolve(process.cwd(), './app/pages')
  ],
  use: {
    loader: require.resolve('babel-loader')
  }
}

别名规范化

将框架与业务模块区分命名,例如:

  • $elpisCurl:框架模块
  • businessComponentConfig:业务组件配置

第六步:公共组件扩展机制

为了支持业务项目扩展公共组件,我们提供健壮的别名配置:

ini 复制代码
const aliasMap = {};
const blankModulePath = path.resolve(__dirname, '../libs/blank.js');
​
const businessComponentConfigPath = path.resolve(process.cwd(), './app/components/config.js');
aliasMap['$businessComponentConfig'] = fs.existsSync(businessComponentConfigPath)
  ? businessComponentConfigPath
  : blankModulePath;

最终合并配置:

javascript 复制代码
import BusinessComponentConfig from '$businessComponentConfig';
​
export default {
  ...componentConfig,
  ...BusinessComponentConfig
};

第七步:发布 NPM 包

确保使用官方源并登录:

arduino 复制代码
npm config set registry https://registry.npmjs.org/
npm login
npm whoami
npm publish --access public

总结

一个成熟的 NPM 包不仅仅是代码的集合,更是开发者与使用者之间的契约。Elpis 的抽离过程强调了以下几点:

  • 模块化设计与业务解耦
  • 灵活的打包与配置机制
  • 健壮的扩展能力与别名规范
  • 清晰的文档与使用指南

未来,我们将继续优化 Elpis 的架构,提升其在企业级应用中的适配性与开发体验。

相关推荐
Demoncode_y11 分钟前
Vue3中基于路由的动态递归菜单组件实现
前端·javascript·vue.js·学习·递归·菜单组件
杨超越luckly12 分钟前
HTML应用指南:利用POST请求获取全国中国工商农业银行网点位置信息
大数据·前端·html·数据可视化·银行网点
皮蛋瘦肉粥_12131 分钟前
pink老师html5+css3day02
前端·css3·html5
qianmo202137 分钟前
基于pycharm实现html文件的快速实现问题讨论
前端·html
IT_陈寒37 分钟前
SpringBoot3踩坑实录:一个@Async注解让我多扛了5000QPS
前端·人工智能·后端
kura_tsuki41 分钟前
[Web网页] 零基础入门 HTML
前端·html
岁月宁静1 小时前
🎨 打造 AI 应用的 “门面”:Vue3.5 + MarkdownIt 实现高颜值、高性能的答案美化组件
前端·javascript·vue.js
golang学习记1 小时前
从0死磕全栈之Next.js Server Actions 入门实战:在服务端安全执行逻辑,告别 API 路由!
前端
光影少年1 小时前
vue3新增哪些内容以及api更改了哪些
前端·vue.js·掘金·日新计划
这儿有一堆花1 小时前
三种 弹出广告 代码开发实战
前端·html