繁体   English   中英

JavaScript模块和Web应用程序插件

[英]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

所以我们说主要是你的应用程序的入口点。 它使用plugin1plugin2 ,两者都使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM