我正在尝试通过vue-cli-service
在Vue中构建模块化应用程序。主应用程序和模块是位于不同文件夹中的独立项目,其结构如下:
-- app/package.json
/src/**
-- module1/package.json
/src**
-- module2/package.json
/src**
这个想法是让Vue应用程序完全不知道运行时可以使用的应用程序模块,这些模块本身是用vue-cli-service build --target lib
编译到本地moduleX/dist
文件夹中的,指向该软件包。 json“主要”和“文件”节点。
我的第一个想法(现在只是出于开发速度的目的)是将模块作为本地NPM软件包添加到应用程序中,使用观察程序进行构建,并使用观察程序本身为应用程序提供服务,以便对依赖模块进行任何更改(我认为)会自动分发到主应用程序。
因此,应用程序的package.json
包含以下依赖项:
...
"module1": "file:../module1",
"module2": "file:../module2",
...
这种依赖关系意味着可以随时删除,或者通常根据需要进行组合,只需重新编译应用程序,一切都可以正常工作。
我现在正在尝试了解如何动态加载和激活应用程序中的模块,因为我不能像这样使用动态导入:
import(/* webpackMode: "eager" */ `module1`).then(src => {
src.default.boot();
resolve();
});
因为基本上我不知道'module1','module2'等...
在OOP世界中,我只会使用实现特定接口的依赖注入检索类,但是在JS / TS中,我不确定它是否可行。
有没有办法做到这一点?
答案 0 :(得分:1)
与package.json
玩杂耍对我来说不是一个好主意-无法扩展。我会做什么:
package.json
中所有可用的“模块” js
文件(或在package.json
内拥有自己的道具)module.exports = {
'default': ['module1', 'module2', 'module3'],
'clientA': ['module1', 'module2', 'module4'],
'clientB': ['module2', 'module3', 'module4']
}
const fs = require('fs')
const _ = require('lodash')
const modulesConfig = require(`your module config js`)
const configurationName = process.env.MY_APP_CONFIGURATION ?? 'default'
const modules = modulesConfig[configurationName]
const template = fs.loadFileSync('name of template file')
const templateCompiled = _.template(template)
const generatedJS = templateCompiled({ `modules`: modules })
fs.writeFileSync('bootModules.js', generatedJS)
bootModules.js
编写模板。最简单的是:<% _.forEach(modules , function(module) { %>import '<%= module %>' as <%= module %><% }); %>;
bootModules.js
导入您的应用MY_APP_CONFIGURATION
ENV变量来切换所需的模块配置-不仅在开发过程中有效,而且您还可以使用不同的MY_APP_CONFIGURATION
值针对相同的仓库设置不同的CI流程这样,您可以将所有配置都放在一个位置,无需在每次构建之前更改package.json
,您可以通过简单的机制在不同的模块配置之间切换,并且每个构建(捆绑)仅包含所需的模块....
答案 1 :(得分:0)
在OOP世界中,我只会使用实现特定接口的依赖注入检索类,但是在JS / TS中,我不确定它是否可行。
为什么不呢?
除此之外,对于JS / TS,您不限于使用实现特定接口的类:您只需要定义模块的接口(即module.exports
)并在库条目中尊重它( vue build lib)。
编辑:阅读评论可能我理解了请求。
每个模块都应遵循以下接口(在vue库条目的文件中)
export function isMyAppModule() {
return true;
}
export function myAppInit() {
return { /* what you need to export */ };
}
比在您的应用中
require("./package.json").dependencies.forEach(name => {
const module = require(name);
if(! module.isMyAppModule || module.isMyAppModule() !== true) return;
const { /* the refs you need */ } = module.myAppInit();
// use your refs as you need
});