Reactjs 如何为React with Webpack进行React本机风格的多版本构建
动机 我正在维护一个应用程序,该应用程序为许多单独的品牌贴上白色标签,这些品牌主要在风格上有所不同,但有时在核心用户体验上也有所不同。当前的(主干)解决方案涉及将共享代码保存在单独的repo中,然后使用Grunt构建单独的应用程序,每个项目的大部分样式代码和一些视图覆盖位于其自己的文件夹中。我们只需使用shell脚本一个接一个地运行所有grunt任务。我们将继续构建这个东西的新版本,并希望最小化重复代码,这已经成为遗留版本中的一个主要问题 期望的结果 React Native packager同时构建其应用程序的两个版本。它首先查看导入语句,如“/ComponentA.js”中的Reactjs 如何为React with Webpack进行React本机风格的多版本构建,reactjs,webpack,Reactjs,Webpack,动机 我正在维护一个应用程序,该应用程序为许多单独的品牌贴上白色标签,这些品牌主要在风格上有所不同,但有时在核心用户体验上也有所不同。当前的(主干)解决方案涉及将共享代码保存在单独的repo中,然后使用Grunt构建单独的应用程序,每个项目的大部分样式代码和一些视图覆盖位于其自己的文件夹中。我们只需使用shell脚本一个接一个地运行所有grunt任务。我们将继续构建这个东西的新版本,并希望最小化重复代码,这已经成为遗留版本中的一个主要问题 期望的结果 React Native packager同
import ComponentA,然后查找ComponentA.android.js
或ComponentA.ios.js
,如果找不到特定于平台的组件,则返回导入ComponentA.js
。我想在Webpack中复制此行为。因此,我想要一个如下所示的文件夹:
react_clients/src/components
|_ ComponentB.js // import ComponentA from './ComponentA.js';
|_ ComponentA.js
|_ ComponentA.brand1.js
|_ ComponentA.brand2.js
...
const getPaths = require('./paths.prod');
...
module.exports = function(projectName) {
const paths = getPaths(projectName);
const JS_PROJECT_EXTENSION = `.${projectName}.js`;
const STYLE_PROJECT_EXTENSION = `.${projectName}.pcss`;
const extensions = [JS_PROJECT_EXTENSION, '.js', '.json', '.jsx', STYLE_PROJECT_EXTENSION, '.pcss'];
...
return {
...
output: {
...
filename: projectName + '-assets/js/[name].[chunkhash:8].js',
chunkFilename: projectName + '-assets/js/[name].[chunkhash:8].chunk.js',
...
}
... [etc, adding projectName to any output that needs to be built separately]
};
}
网页包应按如下方式构建组件B.js:
brand1.bundle.js
从ComponentA.brand1.js导入
brand2.bundle.js
从ComponentA.brand2.js导入
brand3.bundle.js
和brand4.bundle.js
从ComponentA.js导入
这也适用于样式,理想情况下使用相同的命名约定
如有必要,可以使用不同的Webpack.config文件或接受命令行参数为每个版本分别运行Webpack。关键是要避免重复应用程序代码
当前代码
Webpack的起点是一个新生成并弹出的create react app
项目
附言:如果这是重复的,请提前道歉,但这是一个非常棘手的问题。我怀疑答案与的高级配置有关,但目前还无法找到答案 好了,伙计们,这就是我最后要做的:
Dev
在.env.development
中,我为要进行开发的项目的名称指定了一个变量:
REACT_APP_VERSION_NAME=brand1
然后在webpack.config.dev.js
中,我利用模块解析实现上述行为:
const JS_PROJECT_EXTENSION = `.${process.env.REACT_APP_VERSION_NAME}.js`;
const STYLE_PROJECT_EXTENSION = `.${process.env.REACT_APP_VERSION_NAME}.pcss`;
const extensions = [JS_PROJECT_EXTENSION, '.js', '.json', '.jsx', STYLE_PROJECT_EXTENSION, '.pcss'];
...
module.exports = {
...
extensions,
...
}
然后在代码中,我可以简单地执行以下操作:
import ComponentA from './componentA';
import Styles from './styles';
一切都按预期进行
生产
我没有在.env.production
中指定REACT\u APP\u VERSION\u NAME
。相反,相关的配置文件导出函数,我迭代我想要构建的版本
首先,我创建了一个单独版本的config/path.js
,它导出一个函数而不是一个静态对象:
module.exports = function(projectName) {
return {
...
appBuild: resolveApp('build/' + projectName),
...
};
}
我的webpack.config.prod.js
如下所示:
react_clients/src/components
|_ ComponentB.js // import ComponentA from './ComponentA.js';
|_ ComponentA.js
|_ ComponentA.brand1.js
|_ ComponentA.brand2.js
...
const getPaths = require('./paths.prod');
...
module.exports = function(projectName) {
const paths = getPaths(projectName);
const JS_PROJECT_EXTENSION = `.${projectName}.js`;
const STYLE_PROJECT_EXTENSION = `.${projectName}.pcss`;
const extensions = [JS_PROJECT_EXTENSION, '.js', '.json', '.jsx', STYLE_PROJECT_EXTENSION, '.pcss'];
...
return {
...
output: {
...
filename: projectName + '-assets/js/[name].[chunkhash:8].js',
chunkFilename: projectName + '-assets/js/[name].[chunkhash:8].chunk.js',
...
}
... [etc, adding projectName to any output that needs to be built separately]
};
}
最后,只需将scripts/build.js
中的大部分操作包装成一个循环:
...
[various imports]
...
process.argv[2].split(' ').forEach(projectName => {
const config = require('../config/webpack.config.prod')(projectName);
const paths = require('../config/paths.prod')(projectName);
...
[rest of build.js as normal]
}
之后,只需将服务器指向每个版本的正确文件,并在需要构建时运行warn build“brand1 brand2”
我会接受这个答案,因为它现在对我有效,但我很想听到未来任何人的潜在改进