Webpack:如何使用动态捆绑组合两个完全独立的捆绑包
Webpack: How can I combine two completely separate bundles using dynamic bundling
我花了很多时间研究这个,但无济于事。我知道如何使用 import
promise API.
在 Webpack 中进行代码拆分和动态捆绑
但是,我的用例是我有两个完全独立的包,分别使用不同的 webpack 构建生成。为了让您了解,我正在构建 React 组件,并且需要将 React 组件动态加载到已在不同进程中编译的页面中。这有可能做出反应吗?我确实可以控制两个 webpack 构建,所以我可以排除依赖项等。
更新: 我刚刚查看了 Vue.js,以及它如何允许开发人员注册 Vue.js 组件,然后在稍后的代码中引用它们。我可能会在我的页面脚本之前加载我的 Vue.js 组件脚本。我正在尝试看看我是否可以在 React 中做类似的事情。
我对你的理解是否正确:你基本上得到了
- 自定义 React 组件库(由 Webpack build #1 构建)
- 需要使用部分(全部)这些组件的 React 应用程序(由 Webpack build #2 构建,与 #1 完全分开)
?
如果是,请继续阅读。
"Is this possible in react?"问题应该是"Is this possible in Webpack?",答案是 "Yes"。以下是使用 Webpack 2 测试的,但也应该适用于 v.1.
我们称您的项目为 Lib
(您的 React 组件库)和 App
(库使用者)。
在Lib
项目中:
创建一个入口点文件,比如 index.js
,导出所有自定义 React 组件,如下所示:
import {Button} from './button';
import {DatePicker} from './DatePicker';
import {TextBox} from './textBox';
export const MyComponentLib = {
Button,
DatePicker,
TextBox
};
更新webpack.config.js
使项目的bundle成为UMD库(也可以是'var'),设置入口点到上面的index.js
文件。这样做将使您的库在稍后的消费应用程序中通过名为 MyComponentLib
(名称来自上面的 export
)的全局变量可用:
...
output: {
path: './dist',
filename: 'mylib.bundle.js',
libraryTarget: 'umd'
},
...
entry: './index.js',
...
关于 App
项目:
在 index.html
文件中,您将有两个 <script>
标签:一个用于 mylib.bundle.js
(Lib
项目的输出),以及另一个用于 App
项目本身的捆绑包。您可能有更多捆绑包(应用程序、供应商等),我只是在这里简化事情。
更新webpack.config.js
将组件库标记为外部依赖。这里,MyComponentLib
是库可用的全局变量的名称,myComponents
是在 import
语句中使用的名称:
...
externals: {
myComponents: 'MyComponentLib'
},
...
现在,在 App
中,您可以导入这样的组件:
import {DatePicker} from 'myComponents';
这将在 运行 时间通过全局变量从组件库动态加载 DatePicker。
好处:如果你使用 eslint
,你不希望它抱怨缺少你知道是外部的模块;将此添加到您的 .eslintrc
:
...
"settings": {
"import/core-modules": ["myComponents"]
},
...
我花了很多时间研究这个,但无济于事。我知道如何使用 import
promise API.
但是,我的用例是我有两个完全独立的包,分别使用不同的 webpack 构建生成。为了让您了解,我正在构建 React 组件,并且需要将 React 组件动态加载到已在不同进程中编译的页面中。这有可能做出反应吗?我确实可以控制两个 webpack 构建,所以我可以排除依赖项等。
更新: 我刚刚查看了 Vue.js,以及它如何允许开发人员注册 Vue.js 组件,然后在稍后的代码中引用它们。我可能会在我的页面脚本之前加载我的 Vue.js 组件脚本。我正在尝试看看我是否可以在 React 中做类似的事情。
我对你的理解是否正确:你基本上得到了
- 自定义 React 组件库(由 Webpack build #1 构建)
- 需要使用部分(全部)这些组件的 React 应用程序(由 Webpack build #2 构建,与 #1 完全分开)
?
如果是,请继续阅读。
"Is this possible in react?"问题应该是"Is this possible in Webpack?",答案是 "Yes"。以下是使用 Webpack 2 测试的,但也应该适用于 v.1.
我们称您的项目为 Lib
(您的 React 组件库)和 App
(库使用者)。
在Lib
项目中:
创建一个入口点文件,比如
index.js
,导出所有自定义 React 组件,如下所示:import {Button} from './button'; import {DatePicker} from './DatePicker'; import {TextBox} from './textBox'; export const MyComponentLib = { Button, DatePicker, TextBox };
更新
webpack.config.js
使项目的bundle成为UMD库(也可以是'var'),设置入口点到上面的index.js
文件。这样做将使您的库在稍后的消费应用程序中通过名为MyComponentLib
(名称来自上面的export
)的全局变量可用:... output: { path: './dist', filename: 'mylib.bundle.js', libraryTarget: 'umd' }, ... entry: './index.js', ...
关于 App
项目:
在
index.html
文件中,您将有两个<script>
标签:一个用于mylib.bundle.js
(Lib
项目的输出),以及另一个用于App
项目本身的捆绑包。您可能有更多捆绑包(应用程序、供应商等),我只是在这里简化事情。更新
webpack.config.js
将组件库标记为外部依赖。这里,MyComponentLib
是库可用的全局变量的名称,myComponents
是在import
语句中使用的名称:... externals: { myComponents: 'MyComponentLib' }, ...
现在,在 App
中,您可以导入这样的组件:
import {DatePicker} from 'myComponents';
这将在 运行 时间通过全局变量从组件库动态加载 DatePicker。
好处:如果你使用 eslint
,你不希望它抱怨缺少你知道是外部的模块;将此添加到您的 .eslintrc
:
...
"settings": {
"import/core-modules": ["myComponents"]
},
...