我正在开发一个Web应用程序,其中我需要本地定义的React组件来“覆盖”(即优先于)公共代码库中的默认React组件 . 公共代码库是本地应用程序的依赖项,它提供服务器代码和默认组件 .
目标是,如果您需要公共代码库并运行应用程序而不进行任何更改,您将获得应用程序的vanilla版本,但如果您在本地定义组件(例如Logo.jsx),则应用程序应使用该Logo.jsx的版本,而不是底层代码库中的默认组件 .
我的第一个想法是通过在底层代码库中的所有组件中使用动态import语句来解决这个问题,这样在构建时webpack将只查找组件的本地版本,然后在依赖关系图中包含本地版本或者使用后备组件 . 在伪代码中,我对此解决方案的理想版本看起来像这样:
定义自定义导入语句( importCustomOrDefaultComponent.js
):
function importCustomOrDefaultComponent(name) {
// check for a component with this name in the local project, and if so, return
// if no local component exists, return the default component from this repo
}
module.exports = importCustomOrDefaultComponent;
在底层代码库中的所有组件中使用该自定义import语句(例如 NavBar
组件):
import React from 'react';
const importCustomOrDefaultComponent = require('../importCustomOrDefaultComponent.js');
const Logo = importCustomOrDefaultComponent('Logo.jsx')
function NavBar () {
return (
<div>
...
<Logo />
...
</div>
);
};
export default NavBar;
我一直在摆弄它,似乎没有可能像我上面概述的那样,因为webpack不会让你使用这样的自定义导入语句来影响它如何构建依赖项 . 我尝试使用'fs'来编写 importCustomOrDefaultComponent
以查找自定义文件,但是在浏览器中没有't work because webpack tried to bundle the function in with everything else and ultimately I got an error because ' fs'...它似乎只能使用 require('xxx')
或 import xxx from 'xxx'
. 以上是可行的,如果是这样的话, importCustomOrDefaultComponent(name)
将如何运作?
如果这不能通过源中的自定义导入功能来完成,可以通过webpack插件完成吗?我无法找到任何处理这种情况的人 .
如果这不起作用,是否有替代模式来实现我的目标?
-
我已经研究过代码拆分,但是当它拆分代码时,它似乎没有提供一个解决方案,能够动态选择是否在构建时包含组件A或组件B.
-
我还考虑过追求一种插件架构,其中自定义组件以redux状态存储,并且可以动态访问客户端,而不是在构建客户端包时尝试做出这些决定 . 这是一个更好的方法吗?
1 回答
我将在今晚晚些时候用例子重写我的回复,现在这将是我的直接建议:
对于webpack别名或preprocess-loader(以及ifdef语句)来说,这看起来是一个很好的用例 . 对于React Native,只能使用Babel插件,这是另一个故事 .
就个人而言,我喜欢使用babel-plugin-module-alias来支持带有react-native-web目标的React Native .
更新:(如承诺的那样)
Code Splitting (Load Static Modules Dynamically)
由于您使用的是Webpack,因此您需要考虑供应商模块 . 动态加载的最简单方法是通过Webpack的
require()
进行代码拆分 . 自 this method is async 以来,您的周围代码无法同步加载模块 .例:
注意:在旧版本的Webpack中,使用了
require.ensure()
.Using Conditional Compilation
使用
preprocess-loader
,您可以在构建时定义不同的常量 . 这也允许在import
之类的顶级语句周围进行条件登录,这些语句不能在块作用域内使用 . 请记住preprocess
确实将@ifdef
视为真实,无论其 Value 如何,有些情况下您可能需要使用@if
.例:
Using Webpack Aliases
在你的Webpack配置中:
在你的JS里面(来自任何文件,任何目录):