本文内容学习自 哲玄前端 《大前端全栈实践》课程
当需要本地调试待发布的 npm 包时 在包的目录下(elpis)执行命令
bash
npm link
在使用包的目录下(elpis-demo)执行命
bash
npm link "name"
- 这个 name 就是 elpis/package.json 中的name
关于静态资源目录
运行的时候一直会有 /view/project-list 的请求
- elpis/app/view/entry.tpl 中使用了静态资源 /static/xxx
- koaStatic 和 KoaNunjucks 配置的静态资源目录是 process.cwd()/app/public
- 资源请求的是运行目录下的 elpis-demo/app/public
- 实际资源还在 elpis/app/public/static/logo.png,但是 elpis-demo 中没有静态资源导致一直请求不到
- 请求进入 elpis-core/loader/router.js 兜底策略一直请求 app.options.homePage
解决办法:将静态资源移动到 elpis-demo/public 中
devServer 和 element-plus 的按需加载
不能用element-plus的按需引入,不然 npm run build:dev 就一直卡在 webpack 的编译部分,npm run build:prod 就正常运行。
- 虽然 devServer 正常启动了
- 但是 webpack 的编译器根本没有启动,没有将源代码编译为 Bundle。
- 第一步还得自己先手动编译一下(compiler.run),不然一直没编译,没有.tpl的输出。 启动静态服务器,但是没有HMR的效果,加watch只能监听变化,手动刷新才看得到。

自定义SSR页面的扩展
在 webpack.base.js 中修改 entry 和 HtmlWebpackPlugin 来获取全部的入口。
webpack里面的loader会在调用方里面的根目录开始找(即在 elpis-demo 的 node_modules)
-
如果用自己 node_modules 的目录,改为 require.resolve()
- 如果找不到包 用require.resolve()
-
当这个 webpack 配置作为 npm 包被其他项目引用时,loader 的解析路径会基于 elpis 包本身,而不是调用方的 node_modules。
在 elpis-demo/app/pages 目录下写入口文件 entry.xxx.js 和对应组件
自定义 view 页面 dashboard/cutom-view
- 在
elpis-demo/app/pages/dashboard/xxx写页面组件 - 在
elpis-demo/app/pages/dashboard/router.js中进行配置
javascript
module.exports = ({routes, siderRoutes}) => {}
当用户没配置 dashboard/router.js
- try-catch无法解决
- webpack是静态构建,并不是运行时构建,所以会直接报错
javascript
try{
businessDashboardRouterConfig = require('$businessDashboardRouterConfig')
}catch (e) {}
- import的方式无法解决 依旧报错
javascript
(async () => {
businessDashboardRouterConfig = await import('$businessDashboardRouterConfig')
})()
解决方案
-
创建空文件让 webpack 别名指向它作为 fallback
javascriptalias: (() => { const aliasMap = {} const blankModulePath = path.resolve(__dirname, '../libs/blankModule.js') const businessDashboardRouterConfigPath = path.resolve(process.cwd(), 'app/pages/dashboard/router.js') aliasMap['$businessDashboardRouterConfig'] = fs.existsSync(businessDashboardRouterConfigPath) ? businessDashboardRouterConfigPath : blankModulePath return { ...aliasMap, } })(),- 简单、但是需要额外维护文件
-
编译时常量 + if 判断
javascriptnew webpack.DefinePlugin({ __HAS_BUSINESS_DASHBOARD_ROUTER__: fs.existsSync() // true/false }),javascriptif(__HAS_BUSINESS_DASHBOARD_ROUTER__) {...}不会往 window 上挂变量;不会在运行时代码里真的出现 HAS..._ 这个名字。
webpack 在构建时会做常量折叠:如果这个宏是
false,整块if分支会被摇掉
2. 无额外文件,但是定义全局变量进行编译期宏替换 -
反向依赖------由业务入口调用基础库
动态组件扩展 dashboard/schema-view/components
- 在
app/pages/dashboard/complex-view/schema-view/components/下写组件
- components的统一写法
javascript
<script setup>
import { ref } from 'vue'
const name = ref('createForm')
const isShow = ref(false)
const show = () => {
isShow.value = true
}
const close = () => {
isShow.value = false
}
defineExpose({
name,
show,
})
</script>
<template></template>
<style scoped lang="less"></style>
- 配置
app/pages/dashboard/complex-view/schema-view/components/component-config.js
schema-form 控件扩展
- 在
app/pages/widgets/schema-form/complex-view/下写组件
xml
<script setup>
const validate = () => {}
const getValue = () => {}
defineExpose({
name,
validate,
getValue,
})
</script>
<template></template>
<style scoped lang="less"></style>
- 配置
app/pages/widgets/schema-form/form-item-config.js
schema-search-bar 控件的扩展
- 在
app/pages/widgets/schema-search-bar/complex-view/下写组件
xml
<script setup>
const reset = () => {}
const getValue = () => {}
defineExpose({
reset,
getValue,
})
</script>
<template></template>
<style scoped lang="less"></style>
- 配置
app/pages/widgets/schema-search-bar/search-item-config.js
发布
bash
npm config get registry
-> https://registry.npmjs.org/
如果不是, npm config set registry
bash
npm login
npm whoami
npm publish --access public