使用create-react-app创建React应用时是否可以有条件地导入资产?我知道require语法-例如:
import React from "react";
const path = process.env.REACT_APP_TYPE === "app_1" ? "app_1" : "app_2";
const imagePath = require(`./assets/${path}/main.png`);
export default function Test() {
return (
<img src={imagePath} alt="" />
);
}
但是,无论如何,这都会捆绑我的所有资产。
它将加载正确的映像,但仍将所有文件捆绑在一起,形成最终版本。
当我查看最终构建的开发工具时,即使我只想为app_1
加载资产,也可以看到那里的所有资产。
我被迫触摸webpack配置,如果是的话,我应该改变什么?还是有其他方法?
答案 0 :(得分:7)
在React不存在的日子里,我们没有将资产放入我们的JS文件中。我们让CSS决定为哪些选择器加载哪些资产。然后,您可以简单地为相应的元素(甚至整个页面)打开或关闭相应的类,然后中提琴会更改颜色,背景,甚至是形式。纯粹的魔法!
啊。这些是什么时间!
以上所有内容都是正确的,我不明白为什么有人会这样做或建议以其他方式建议这样做。但是,如果您仍然想要这样做(出于任何原因),则可以!最新的create-react-app
通过动态导入和lazy loading为code splitting任意组件提供了开箱即用的支持。您需要做的就是使用import()
语句的括号版本而不是常规的语句。 import()
照常接收请求字符串并返回Promise。而已。动态请求的组件的源代码不会被捆绑,而是存储在单独的块中以按需加载。
之前:
import OtherComponent from './OtherComponent';
function MyComponent() {
return (
<div>
<OtherComponent />
</div>
);
}
之后:
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<OtherComponent />
</div>
);
}
注意,function MyComponent
部分完全相同。
对于那些想知道它是否与CRA或React绑定的人而言,并非如此。 can be used in vanilla JavaScript是一个通用概念。
答案 1 :(得分:6)
您将需要使用webpack(或其他捆绑程序)。捆绑在一起时代码不会运行,因此编译器无法知道遵循哪个逻辑分支(app_1或app_2) )。因此,您必须了解捆绑程序的逻辑才能实现目标。
但是,这并没有看上去那么可怕,因为webpack内置了执行此操作的功能(不需要第三方...)
我会考虑使用webpack.providePlugin
(https://webpack.js.org/plugins/provide-plugin)
或其同级DefinePlugin
(https://webpack.js.org/plugins/define-plugin)
(恐怕这些例子已经浮现在我的头上了,因此它们不太可能在初次通过时起作用。)
示例:
两者都需要提供者模块...
// in path/provider.js
module.exports = {
live: '/path/to/live/image',
dev: '/path/to/dev/image'
}
提供插件示例
// in webpack
new webpack.ProvidePlugin({
imagePath: [
'path/provider', // the file defined above
process.env.ENVIRONMENT // either 'dev' or 'live'
]
}),
// in code
export default function Test() {
return (
<img src={imagePath} alt="" />
);
}
定义插件示例:
// in webpack
new webpack.DefinePlugin({
'process.env.ENVIRONMENT': JSON.stringify(process.env.ENVIRONMENT)
});
// in code
var providers = require('path/provider'); // same path provider as above
export default function Test() {
return (
<img src={providers[process.env.ENVIRONMENT]} alt="" />
);
}
在两种情况下,捆绑器都必须在编译时(在发生捆绑之前)将变量折叠为实际文字值。由于您现在已经将逻辑路径折叠为一个选项,因此现在可以自由捆绑相关资产。
答案 2 :(得分:3)
您不能使用默认CRA设置来做到这一点。
因为如果您的动态需求或动态导入路径不是静态,Webpack将无法确定要包含在其中的资产因此,最终的构建文件夹将从您的./src
文件夹中抓取所有内容,并将其全部放入您的build
文件夹中。
答案 3 :(得分:0)
有一种方法可以使用默认CRA设置
您可以在.env中添加类似内容
REACT_APP_SKIN=1
将您的皮肤资产放入public / css1,public / css2等中,并使用类似的代码将其包含在public / index.html中
<link href="/css%REACT_APP_SKIN%/theme.css" rel="stylesheet">