elpis的npm抽离与发布
前言话接上文在上一个学习阶段中elpis已经基本开发完成了具备了动态生成页面和组件的能力那么在这一章节中我们要做的就是把项目进行改造并发布到npm上去供大家进行使用附上我的npm包npm i yxcheng/augustus抽离过程一本地连接在发布之前我们需要先在本地进行调试这个命令是npm link所以我们需要在本地新建一个demo文件然后通过npm link xxx(此处为npm用户的名称包名) 进行连接二相关文件处理以controller为例当我们把elpis当做一个公共包来使用时我们需要注意的是不仅要挂载业务下的controller到app还需兼容自身的controller所以对如下代码进行改造module.exports (app) { const controller {}; // 读取augusts/controller/**/**.js目录下的文件 const augustsBusinessControllPath path.resolve( __dirname, ..${sep}..${sep}app${sep}controller, ); const augustsFileList glob.sync( path.resolve(augustsBusinessControllPath, .${sep}**${sep}**.js), ); augustsFileList.forEach((file) { handleFile(file); }); // 读取业务/controller/**/**.js目录下的文件 const businessControllPath path.resolve( app.businessPath, .${sep}controller, ); const businessFileList glob.sync( path.resolve(businessControllPath, .${sep}**${sep}**.js), ); businessFileList.forEach((file) { handleFile(file); }); // 把内容加载到app.controller下 function handleFile(file) { // 提取文件名 let name path.resolve(file); // 截取路径 app/controller/custom-module/custom-controller.js custom-module/custom-controller name name.substring( name.lastIndexOf(controller${sep}) controller${sep}.length, name.lastIndexOf(.), ); // 把’-‘统一改为驼峰式 name name.replace(/[_-][a-z]/gi, (s) s.substring(1).toUpperCase()); // 挂在controller到内存app对象中 let tempController controller; const names name.split(sep); for (let i 0, len names.length; i len; i) { if (i len - 1) { const ControllerMoule require(path.resolve(file))(app); tempController[names[i]] new ControllerMoule(); } else { if (!tempController[names[i]]) { tempController[names[i]] {}; } tempController tempController[names[i]]; } } } app.controller controller; };对于自身和即将使用的业务文件进行同样的处理包括extend.js,config.js,middleware.js,router-schema.js,router.js,service.js文件同样依次处理webpack部分的处理1.将 dev 和 prod 两个打包方式暴露出去然后项目就可以通过该函数去执行相应的打包方式const FEBuildDev require(./app/webpack/dev.js); const FEBuildProd require(./app/webpack/prod.js); module.exports { /** * 服务端基础 */ Controller: { Base: require(./app/controller/base.js), }, Service: { Base: require(./app/service/base.js), }, /** * 编译构建前端工程 * params env 环境变量 local/prod */ frontendBuild(env) { if (env local) { FEBuildDev(); } else if (env production) { FEBuildProd(); } }, };2.webpack.base的修改resolve: { extensions: [.js, .vue, .less, .css], alias: (() { const alaisMap {}; const blankModulePath path.resolve(__dirname, ../libs/blank.js); // dashboard路由拓展配置 const businessDashboardRouterConfig path.resolve( process.cwd(), ./app/pages/dashboard/router.js, ); alaisMap[$businessDashboardRouterConfig] fs.existsSync( businessDashboardRouterConfig, ) ? businessDashboardRouterConfig : blankModulePath; // schema-view component 扩展配置 const businessComponentConfig path.resolve( process.cwd(), ./app/pages/dashboard/complex-view/schema-view/components/component-config.js, ); alaisMap[$businessComponentConfig] fs.existsSync( businessComponentConfig, ) ? businessComponentConfig : blankModulePath; // schema-form 扩展配置 const businessFormItemConfig path.resolve( process.cwd(), ./app/pages/widgets/schema-form/form-item-config.js, ); alaisMap[$businessFormItemConfig] fs.existsSync( businessFormItemConfig, ) ? businessFormItemConfig : blankModulePath; // schema-search-bar 扩展配置 const businessSearchItemConfig path.resolve( process.cwd(), ./app/pages/widgets/schema-search-bar/search-item-config.js, ); alaisMap[$businessSearchItemConfig] fs.existsSync( businessSearchItemConfig, ) ? businessSearchItemConfig : blankModulePath; return { vue: require.resolve(vue), babel/runtime/regenerator: require.resolve(babel/runtime/regenerator), babel/runtime/helpers/asyncToGenerator: require.resolve(babel/runtime/helpers/asyncToGenerator), $elpisPages: path.resolve(__dirname, ../../pages), $elpisCommon: path.resolve(__dirname, ../../pages/common), $elpisCurl: path.resolve(__dirname, ../../pages/common/curl.js), $elpisUtils: path.resolve(__dirname, ../../pages/common/utils.js), $elpisWidgets: path.resolve(__dirname, ../../pages/widgets), $elpisHeaderContainer: path.resolve( __dirname, ../../pages/widgets/header-container/header-container.vue, ), $elpisSiderContainer: path.resolve( __dirname, ../../pages/widgets/sider-container/sider-container.vue, ), $elpisSchemaTable: path.resolve( __dirname, ../../pages/widgets/schema-table/schema-table.vue, ), $elpisSchemaForm: path.resolve( __dirname, ../../pages/widgets/schema-form/schema-form.vue, ), $elpisSchemaSearchBar: path.resolve( __dirname, ../../pages/widgets/schema-search-bar/schema-search-bar.vue, ), $elpisStore: path.resolve(__dirname, ../../pages/store), $elpisBoot: path.resolve(__dirname, ../../pages/boot.js), ...alaisMap, }; })(), },配置公共组件部分import createForm from ./create-form/create-form.vue; import editForm from ./edit-form/edit-form.vue; import detailPanel from ./detail-panel/detail-panel.vue; // 业务拓展component配置 import BusinessComponentConfig from $businessComponentConfig; const componentConfig { createForm: { component: createForm, }, editForm: { component: editForm, }, detailPanel: { component: detailPanel, }, }; export default { ...componentConfig, ...BusinessComponentConfig, };这里面改动的部分在于1. 路径别名修改使用之前的路径别名会定位到我们的业务目录下所以需要进行修改2. 由于我们的包中提供了自己的 loader 所以需要使用 require.resolve(相关loader) 包裹起来3. 配置外部公共组件由于我们需要提供给使用者一个扩展公共组件的方法因此除了原先 elpis 自带的公共组件路径外还需要配置一个能够读取项目(业务)公共组件路径的方法npm包发布1. 注册npm账号2. 查看是否具有镜像源如果存在则需要清空3. 登录npm并确认npm名4. 发布npm包// 查看镜像源 npm config get // 清空镜像源 npm config set registry // 登录 npm npm login //会给邮箱发送验证邮件 // 确定当前登录的 npm 账号和package.json里面的name是否对应 npm whoami // 发布 npm npm publish --access public // 公有化提交第一次提交需要进行公有化提交 npm publish一开始npm publish --access public一直403提交不上去查看是因为two-factor authentication查了一下自2025年底起npm 为了安全采取了两项关键措施1.废弃经典令牌传统的 npm login 方式或 Classic Token 已无法满足发布要求。1.强制2FA或等效方案所有粒度令牌Granular Token默认需要2FA验证。然而CLI工具只能接受来自验证器应用如 Google Authenticator的 TOTP 码无法使用 Security Key 或恢复码。这导致了一个矛盾即使您在网页端启用了2FA如果只配置了 Security Key 而未启用 TOTPCLI 发布依然会失败解决方法如下亲测有效生成正确的令牌- 登录 npmjs.com点击右上角头像进入 “Access Tokens”。- 点击 “Generate New Token” 对permission需要允许读写然后日期尽量长一点。-核心步骤务必勾选“Bypass two-factor authentication”选项。这是解决403错误的关键。- 生成并复制以 npm_ 开头的长字符串令牌只显示一次请妥善保存写入令牌执行 npm config set //registry.npmjs.org/:_authToken你的token执行完之后可以通过npm whoami验证是否生效能输出用户名说明 OK之后再npm publish --access public应该问题就没有了本文来源于抖音 哲玄 大前端全栈实践
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2438751.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!