项目背景
简介
将我们的访客系统
项目进行重构(使用亿力提供的前端框架),并嵌入亿力项目中。
目标
1.完成基本功能。
2.对项目进行打包和混淆。
3.将我们项目以 npm 包的方式呈现。
难点
我们的工程需要反向依赖亿力项目内的部分组件
、axios
、store
,编写的页面还需再暴露出去。
技术细节
npm 包的发布与使用
根据此链接了解 npm 包的发布与使用
将主包的组件、axios、store 引入我们的工程
在自己的工程中创建三个类( componentsContainer,storeContainer,axiosContainer),并单例的形式进行向外暴露
//componentsContainer.js
class ComponentsContainer {
components;
getComponents(){
return this.components
}
setComponents(components){
this.components = components
}
}
const componentsContainer = new ComponentsContainer()
export default componentsContainer
//storeContainer.js
class StoreContainer {
store;
//需要异步获取,我的方法比较粗糙。有好的方法请留下你宝贵的意见
getStore() {
let setIntervaler;
return new Promise((resolve, reject) => {
if (!this.store) { //没有strore会一直轮询
setIntervaler = setInterval(() => {
if (this.store) {
resolve(this.store);
clearInterval(setIntervaler);
}
}, 50);
} else {
resolve(this.store);
}
});
}
setStore(store) {
this.store = store;
}
}
const storeContainer = new StoreContainer();
export default storeContainer;
//axiosContainer.js 同上
class AxiosContainer {
axios;
getAxios(){
let setIntervaler
return new Promise((resolve,reject)=>{
if(!this.axios){
setIntervaler = setInterval(()=>{
if(this.axios){
resolve(this.axios)
clearInterval(setIntervaler)
}
},50)
}else{
resolve(this.axios)
}
})
}
setAxios(axios){
this.axios = axios
}
}
const axiosContainer = new AxiosContainer()
export default axiosContainer
外部组件、axios、store 的使用
在需要的vue页面进行引入你需要的组件,引入方式如下。其他正常使用
import componentsContainer from '../../../components/index'
export default {
components: { //引入方式入下
'simple-table':()=>new Promise((resolve,reject)=>{
resolve(componentsContainer.getComponents().SimpleTable)
}),
}
}
对外部传入的axios(已具有拦截等功能)进行二次封装,如添加请求头
import axiosContainer from '../index'
async function axios({ url, data, params, headers, method }) {
const service = await axiosContainer.getAxios()
const userInfo = await setUserInfo()
const roles = await setRoles()
return service({
url,
method,
params,
data,
headers: Object.assign({}, headers, userInfo, roles)
})
}
//使用如下
export function getData(parameter) {
return axios({
url: 'url',
method: 'get',
params: parameter
})
}
store的使用如下
import storeContainer from '../../../../store/index'
//需要使用时
storeContainer.getStore().then(store=>{
this.orgNo = store.getters.userInfo.orgCode
this.visible = true
this.$refs?.table?.refresh(true)
})
打包和混淆
- 在package.json中添加新命令,设置你的目标入口文件
packages/index.js
(我的文件路径,你放你的)
"lib": "vue-cli-service build --target lib packages/index.js"
- 新建vue.config.js专门用于打包
const path = require('path');
const TerserPlugin = require('terser-webpack-plugin') //混淆的插件
module.exports = {
lintOnSave: false,
productionSourceMap: false,
publicPath:'/',
outputDir:"visitor-lib", //输出的文件夹名称
chainWebpack: config => {
config.module
.rule('js')
.include.add(path.resolve(__dirname, 'packages'))
.end()
.use('babel')
.loader('babel-loader')
.tap(options => {
return options;
});
},
configureWebpack: (config) => {
let optimization = {
minimize: true,
minimizer: [new TerserPlugin({
terserOptions: {
warnings: false,
compress: {
drop_console: true,
drop_debugger: false,
pure_funcs: ['console.log']
},
}
})],
}
Object.assign(config, {
optimization
})
}
};
该npm包的使用
导包
npm install yili-visitor
main.js 配置
main.js
import store from "./store";
import { axios } from "./utils/request";
import { componentsContainer,storeContainer,axiosContainer } from 'yili-visitor'
import { SimpleTable } from '@/components'
componentsContainer.setComponents({ SimpleTable }) //注入组件到npm包中
storeContainer.setStore(store)
axiosContainer.setAxios(axios)
页面的使用
例如
<template>
<demo></demo>
</template>
<script>
import { demo } from 'yili-visitor'
export default {
data(){
return{}
},
components:{
demo
}
}
</script>