尝试使用 webpack ignorePlugin 从最终包中删除 'react-hot-loader'
Trying to remove 'react-hot-loader' from final bundle using webpack ignorePlugin
react-hot-loader
文档是这样说的:
https://www.npmjs.com/package/react-hot-loader
Note: You can safely install react-hot-loader as a regular dependency instead of a dev dependency as it automatically ensures it is not executed in production and the footprint is minimal.
尽管它是这么说的。我的目标是:
- 我想从我的生产包中删除
react-hot-loader
。
- 我还想要一个
App.js
文件。这应该适用于 DEV 和 PROD。
我与 react-hot-loader
相关的唯一命令在我的 App.js
文件中:
App.js
import { hot } from 'react-hot-loader/root';
import React from 'react';
import Layout from './Layout/Layout';
function App() {
console.log('Rendering App...');
return(
<Layout/>
);
}
export default process.env = hot(App);
如果我 运行 就像这样,我最终会在我的 app.js
转译和捆绑文件中得到以下行:
/* WEBPACK VAR INJECTION /(function(process) {/ harmony import / var react_hot_loader_root__WEBPACK_IMPORTED_MODULE_0__ = webpack_require(/! react-hot-loader/root */ "wSuE");
这是预期的。
但是如果我将 App.js 文件更改为:
AppV2.js
import { hot } from 'react-hot-loader/root'; // KEEPING THE IMPORT
import React from 'react';
import Layout from './Layout/Layout';
function App() {
console.log('Rendering App...');
console.log(window);
return(
<Layout/>
);
}
// export default hot(App); <--- COMMENTED OUT THE hot() LINE
export default App;
然后我将这一行添加到我的 webpack.config.js
webpack.config.js
plugins:[
new webpack.IgnorePlugin(/react-hot-loader/)
]
我将使用以下行得到一个新的转译 app.js
文件:
*** !(function webpackMissingModule() { var e = new Error("Cannot find module 'react-hot-loader/root'"); e.code = 'MODULE_NOT_FOUND'; throw e; }());
注意:上一行中的第一个“***”字符实际上并不存在。我必须将它们添加到!引号中显示的感叹号。不知道为什么,但你不能用感叹号开始引用。
问题
IgnorePlugin 不是应该完全忽略 react-hot-loader
包吗?为什么它被标记为丢失?看到它甚至没有在代码中使用(因为我已经注释掉了 hot()
调用)。
Ignore Plugin 仅在包生成中排除该特定模块。但是,它不会从您的源代码中删除对该模块的引用。因此,您的 webpack 输出会抛出该错误。
绕过此错误的一种方法是使用 DefinePlugin
为 react-hot-loader
创建虚拟存根。更多关于 here.
也就是说,如果 NODE_ENV
是 production
,react-hot-loader
本身会代理子项而不会发生任何变化。检查 here and here。所以在生产模式下,除了直接 returns 你的组件的 hot()
函数调用之外,没有其他事情发生。
另一个选项可以是:
// App.js
export default function AppFactory() {
if (process.env.NODE_ENV === "development") {
return hot(App);
} else {
return App;
}
}
// index.js:
import AppFactory from './App';
const App = AppFactory();
// ...
<App />
现在由于 webpack 在构建时创建包,它知道模式是开发模式还是生产模式(更多关于 build modes) and should be able to eliminate the dead code with tree shaking and UglifyjsWebpackPlugin。
确保如果您使用的是 Babel,它不会将您的代码转换为 CommonJS - 请参阅结论部分,tree shaking 页面的第 2 点。
将环境模式传递给 babel。
"scripts": {
"build-dev": "webpack --node-env development",
"build-prod": "webpack --node-env production",
},
react-hot-loader
文档是这样说的:
https://www.npmjs.com/package/react-hot-loader
Note: You can safely install react-hot-loader as a regular dependency instead of a dev dependency as it automatically ensures it is not executed in production and the footprint is minimal.
尽管它是这么说的。我的目标是:
- 我想从我的生产包中删除
react-hot-loader
。 - 我还想要一个
App.js
文件。这应该适用于 DEV 和 PROD。
我与 react-hot-loader
相关的唯一命令在我的 App.js
文件中:
App.js
import { hot } from 'react-hot-loader/root';
import React from 'react';
import Layout from './Layout/Layout';
function App() {
console.log('Rendering App...');
return(
<Layout/>
);
}
export default process.env = hot(App);
如果我 运行 就像这样,我最终会在我的 app.js
转译和捆绑文件中得到以下行:
/* WEBPACK VAR INJECTION /(function(process) {/ harmony import / var react_hot_loader_root__WEBPACK_IMPORTED_MODULE_0__ = webpack_require(/! react-hot-loader/root */ "wSuE");
这是预期的。
但是如果我将 App.js 文件更改为:
AppV2.js
import { hot } from 'react-hot-loader/root'; // KEEPING THE IMPORT
import React from 'react';
import Layout from './Layout/Layout';
function App() {
console.log('Rendering App...');
console.log(window);
return(
<Layout/>
);
}
// export default hot(App); <--- COMMENTED OUT THE hot() LINE
export default App;
然后我将这一行添加到我的 webpack.config.js
webpack.config.js
plugins:[
new webpack.IgnorePlugin(/react-hot-loader/)
]
我将使用以下行得到一个新的转译 app.js
文件:
*** !(function webpackMissingModule() { var e = new Error("Cannot find module 'react-hot-loader/root'"); e.code = 'MODULE_NOT_FOUND'; throw e; }());
注意:上一行中的第一个“***”字符实际上并不存在。我必须将它们添加到!引号中显示的感叹号。不知道为什么,但你不能用感叹号开始引用。
问题
IgnorePlugin 不是应该完全忽略 react-hot-loader
包吗?为什么它被标记为丢失?看到它甚至没有在代码中使用(因为我已经注释掉了 hot()
调用)。
Ignore Plugin 仅在包生成中排除该特定模块。但是,它不会从您的源代码中删除对该模块的引用。因此,您的 webpack 输出会抛出该错误。
绕过此错误的一种方法是使用 DefinePlugin
为 react-hot-loader
创建虚拟存根。更多关于 here.
也就是说,如果 NODE_ENV
是 production
,react-hot-loader
本身会代理子项而不会发生任何变化。检查 here and here。所以在生产模式下,除了直接 returns 你的组件的 hot()
函数调用之外,没有其他事情发生。
另一个选项可以是:
// App.js
export default function AppFactory() {
if (process.env.NODE_ENV === "development") {
return hot(App);
} else {
return App;
}
}
// index.js:
import AppFactory from './App';
const App = AppFactory();
// ...
<App />
现在由于 webpack 在构建时创建包,它知道模式是开发模式还是生产模式(更多关于 build modes) and should be able to eliminate the dead code with tree shaking and UglifyjsWebpackPlugin。
确保如果您使用的是 Babel,它不会将您的代码转换为 CommonJS - 请参阅结论部分,tree shaking 页面的第 2 点。
将环境模式传递给 babel。
"scripts": {
"build-dev": "webpack --node-env development",
"build-prod": "webpack --node-env production",
},