[英]JavaScript modules and web application plugins
我维护一个(PHP)Web应用程序,它包含一个应用程序核心和几个可以添加到核心的插件。 应用程序的每个实例都可以有一组自定义插件,具体取决于实例的用途。 应用程序核心和插件是在各自的存储库中开发的。
如果安装了插件,它会将JavaScript注入到前端的模板中。 这可能如下所示:
<script src="core.min.js"></script>
<script src="plugin-1.min.js"></script>
<script src="plugin-2.min.js"></script>
排序很重要,因为插件可能会使用来自核心的资源或之前注入的其他插件。 目前,这种资源共享是作为全局范围内的单个变量实现的,该变量收集由核心和插件“导出”的资源。 在插件中,可以通过此全局变量访问和使用资源:
var resource = myapp.core.resource;
现在我的问题是:有没有办法用ES6模块(使用Webpack或类似的东西)实现上述的核心/插件架构? 我想使用更现代的方式开发JavaScript甚至使用TypeScript,但我不知道是否或如何做到这一点。 我知道有可能从插件中的核心JavaScript导入一些资源,但是这也不会被编译到插件的JavaScript文件中吗? 这会复制代码。
澄清:
核心应用程序和插件是在单独的存储库中开发的,例如:
core/src/main.js
plugin-1/src/main.js
plugin-2/src/main.js
每个存储库的代码都是自己构建到PHP包中的。 最终的应用程序实例由应用程序核心和作为PHP包安装的几个插件组成。 安装PHP包时不重建JavaScript。
我可以在这样的插件中从应用程序核心导入一些资源:
import {resource} from '../../../core/src/main'
但是,这会复制应用程序核心的代码,因为核心和插件是分开构建的。
我要问的是,是否可以创建一个“知道”核心和插件之间的共享变量的构建配置。 例如,如果我在核心中定义一个Main
类,它可以构建到全局变量myapp.core.Main
。 如果我然后在其中一个插件中导入Main
,则可以解析为使用变量myapp.core.Main
。 这就是当前实现的工作方式,但它都是手动定义的。 也许有更聪明的方式使用像Webpack这样的现代构建工具。
将模块打包到bundle.js
的一般要点是,虽然它们在src
被折射,但它们仍然捆绑在一个捆绑文件中(有时你会因为各种原因将它分成几个)。 Webpack知道不重复代码,这是它的基础。 我举个例子:
SRC:
root/src
root/src/main.js
root/src/plugin1.js
root/src/plugin2.js
root/src/utils/util1.js
所以我们说主要是你的应用程序的入口点。 它使用plugin1
和plugin2
,两者都使用util1
。
main.js:
import plugin1 from './plugin1'
import plugin2 from './plugin2'
//... Do stuff
plugin1.js:
import util1 from './utils/util1.js';
export default const plugin1 = ()=>{
//.. Do stuff also with util1
}
plugin2.js:
import util1 from './utils/util1.js';
export default const plugin2 = ()=>{
//.. Do stuff also with util1
}
util1.js:
export default const util1 = ()=>{
//.. Do util things
}
当您使用webpack捆绑此代码时,它将知道不重复代码。 如果你正确配置它们,它也会知道要做很多生产质量的东西(老实说,默认情况下它也是非常好的开始)。 结果将进入捆绑包和生成的index.html文件(我建议使用此方法,因为您可以开始散列源的名称并避免在更新时缓存问题。)的手册。
DIST:
root/dist/index.html
root/dist/bundle.js
index.html :
<!-- Would / Should have a script tag for the bundle. -->
<script src="bundle.js">
bundle.js:
// Here you would get a minified/uglified etc. version of your JS which is optimized according to the config. You will not get code repetition.
请记住,您有核心和插件的单独存储库,我建议为核心和每个插件创建包。
因此,在核心中,您将在plugin1 "name": "@scope/plugin1"
使用"name": "@scope/core"
的package.json "name": "@scope/plugin1"
等
然后,您将构建所有包,例如使用webpack并发布结果或将其放在某处。
之后,您可以使用带有import
语句的es6模块。
让我们说在plugin2中你需要使用核心功能以及plugin1中的东西。
// package.json for plugin2
{
"name": "@scope/plugin2",
"dependencies": {
"@scope/core": "1.0.0",
"@scope/plugin1": "1.0.0"
}
}
// some javascript in plugin2
import {coreResource} from '@scope/core';
import {p1Resource} from '@scope/plugin1';
如果你不想发布你的代码,那么你可以将它放在localy的某个地方并在依赖项中引用它
// package.json for plugin2
{
"name": "@scope/plugin2",
"dependencies": {
"@scope/core": "file:/path/to/core",
"@scope/plugin1": "file:/path/to/plugin1"
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.