react-scripts で developmentモードでビルドする
(最初に書いたのがいつか分からない。 2019年? 2020年5月に react-scripts を 3.4.1 にも一部修正の上適用できることを確認。)
react-scripts でビルドすると、バンドル化の際にソースが圧縮されて目視確認しにくいので、developmentモードでwebpackを呼び出せるようにする。
私の環境(上のページと少しバージョンが違うので、修正内容も異なる)
react-scripts: ver 3.01
3.4.1(2020.5現在の最新)にも、react-scripts.jsにて、一部修正必要だったけど、適用可。
ただし、3.4.1の場合、複数のReactアプリを entryに記載した場合に、webpack.config.jsに以下の修正が必要だった。適用しないと、 cannot read property 'filter' of undefined その他の貧弱なエラーメッセージから原因を突き止めるのは極めて困難とおもわれたので、以下の修正案(私の手元でもそのまま動作)の報告はとてもありがたかった。
webpack: ver 4.29.6 (react-scripts 3.4.1にしたときは、 webpack 4.42.0 を使用)
以下の変更を加える。npmで react-scriptsをインストール済の開発環境を構築済であることが前提。
code: package.json
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
+ "dev": "react-scripts dev",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
code: ./node_modules/react-scripts/bin/react-scripts.js
--- 8,32 ----
'use strict';
const spawn = require('react-dev-utils/crossSpawn');
const args = process.argv.slice(2);
const scriptIndex = args.findIndex(
! x => x === 'build' || x === 'dev' || x === 'eject' || x === 'start' || x === 'test'
);
const script = scriptIndex === -1 ? args0 : argsscriptIndex; const nodeArgs = scriptIndex > 0 ? args.slice(0, scriptIndex) : [];
switch (script) {
case 'build':
+ case 'dev':
case 'eject':
case 'start':
case 'test': {
(switch文は、ver. 3.4.1 だと includes()で書き換えられていた。)
./node_modules/react-scripts/scripts/build.js を./node_modules/react-scripts/scripts/dev.jsにコピーして以下の変更を加える
code: ./node_modules/react-scripts/scripts/dev.js
***************
*** 9,16 ****
'use strict';
// Do this as the first thing so that any code reading it knows the right env.
! process.env.BABEL_ENV = 'production';
! process.env.NODE_ENV = 'production';
// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
--- 9,18 ----
'use strict';
// Do this as the first thing so that any code reading it knows the right env.
! //process.env.BABEL_ENV = 'production';
! //process.env.NODE_ENV = 'production';
! process.env.BABEL_ENV = 'development';
! process.env.NODE_ENV = 'development';
// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
***************
*** 60,66 ****
}
// Generate configuration
! const config = configFactory('production');
// We require that you explicitly set browsers and do not fall back to
// browserslist defaults.
--- 62,69 ----
}
// Generate configuration
! //const config = configFactory('production');
! const config = configFactory('development');
code: ./node_modules/react-scripts/config/paths.js
***************
*** 78,83 ****
--- 78,84 ----
dotenv: resolveApp('.env'),
appPath: resolveApp('.'),
appBuild: resolveApp('build'),
+ appDev: resolveApp('build'),
appPublic: resolveApp('public'),
appHtml: resolveApp('public/index.html'),
appIndexJs: resolveModule(resolveApp, 'src/index'),
***************
*** 101,106 ****
--- 102,108 ----
dotenv: resolveApp('.env'),
appPath: resolveApp('.'),
appBuild: resolveApp('build'),
+ appDev: resolveApp('build'),
appPublic: resolveApp('public'),
appHtml: resolveApp('public/index.html'),
appIndexJs: resolveModule(resolveApp, 'src/index'),
***************
*** 136,141 ****
--- 138,144 ----
dotenv: resolveOwn('template/.env'),
appPath: resolveApp('.'),
appBuild: resolveOwn('../../build'),
+ appDev: resolveOwn('../../build'),
appPublic: resolveOwn('template/public'),
appHtml: resolveOwn('template/public/index.html'),
appIndexJs: resolveModule(resolveOwn, 'template/src/index'),
code: /node_modules/react-scripts/config/webpack.config.js
***************
*** 159,167 ****
].filter(Boolean),
output: {
// The build folder.
! path: isEnvProduction ? paths.appBuild : undefined,
! // Add /* filename */ comments to generated require()s in the output.
! pathinfo: isEnvDevelopment,
// There will be one main bundle, and one file per asynchronous chunk.
// In development, it does not produce real files.
filename: isEnvProduction
--- 159,169 ----
].filter(Boolean),
output: {
// The build folder.
! //path: isEnvProduction ? paths.appBuild : undefined,
! path: isEnvProduction ? paths.appBuild : isEnvDevelopment ? paths.appDev: undefined,
! // Add /* filename */ comments to generated require()s in the output.
! pathinfo: isEnvDevelopment,
!
3.4.1の場合で、もし、複数のReactアプリを entryに記載した場合には、さらに以下の追加パッチを適用(行番号は違うと思う)
code: /node_modules/react-scripts/config/webpack.config.js react-script-3.4.1 用の追加修正
***************
*** 638,646 ****
return manifest;
}, seed);
! const entrypointFiles = entrypoints.main.filter(
! fileName => !fileName.endsWith('.map')
! );
return {
files: manifestFiles,
--- 644,654 ----
return manifest;
}, seed);
! const entrypointFiles = {};
! Object.keys(entrypoints).forEach(entrypoint => {
! });
return {
files: manifestFiles,