使用 React.lazy、Suspense 和 react-router-dom 进行代码拆分不起作用
Code splitting with React.lazy, Suspense and react-router-dom doesn't work
我正在尝试设置一个非常基本的示例,类似于:https://reactjs.org/docs/code-splitting.html#route-based-code-splitting
它应该根据当前路由动态延迟加载路由组件(ModuleOne 或 ModuleTwo)及其依赖项。
然而,代码拆分似乎不起作用,所有内容都包含在一个包中。
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index',
output: {
filename: '[name].bundle.js',
chunkFilename: '[name].bundle.js',
path: path.resolve(__dirname, '../dist'),
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'awesome-typescript-loader',
exclude: /node_modules/,
}
],
},
resolve: {
modules: ['node_modules', path.resolve(__dirname, '../src')],
extensions: ['.js', '.jsx', '.ts', '.tsx'],
}
};
App.tsx
import * as React from 'react';
import { HashRouter as Router, Link, Route, Switch } from 'react-router-dom';
import * as styles from './App.scss';
const LazyModuleOne = React.lazy(() => import('../modules/ModuleOne/ModuleOne'));
const LazyModuleTwo = React.lazy(() => import('../modules/ModuleTwo/ModuleTwo'));
const App = () => (
<Router>
<div className={styles.wrapper}>
<nav>
<Link to="/">Start</Link>
<Link to="/module-one">Module One</Link>
<Link to="/module-two">Module Two</Link>
</nav>
<main>
<React.Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route path="/module-one" component={LazyModuleOne} />
<Route path="/module-two" component={LazyModuleTwo} />
</Switch>
</React.Suspense>
</main>
</div>
</Router>
);
export default App;
ModuleOne.tsx
import * as React from 'react';
import * as _ from 'lodash';
import { RouteComponentProps } from 'react-router';
const apples = _.fill([1,2,3], 'apple');
const ModuleOne: React.FC<RouteComponentProps> = () => (
<div>
<div>ModuleOne</div>
<div>There are {apples.length} apples</div>
</div>
)
export default ModuleOne;
ModuleTwo.tsx
import * as React from 'react';
import * as R from 'ramda';
import { RouteComponentProps } from 'react-router';
const cherries = [1,2,3];
const ModuleTwo: React.SFC<RouteComponentProps> = () => (
<div>
<div>ModuleTwo</div>
<div>There are {R.length(cherries)} cherries</div>
</div>
)
export default ModuleTwo;
演示:
有谁知道为什么基于路由的代码拆分无法按预期工作?
我的 React 版本是 16.4.0,可以使用!
我和你唯一的区别:
我正在使用 BrowserRouter。
你使用了 HashRouter。
我找到了解决方案。这与 TypeScript
相关。我需要设置:
{
"compilerOptions": {
"module": "esnext",
},
}
而不是 commonjs
。
现在代码拆分工作正常。
我正在尝试设置一个非常基本的示例,类似于:https://reactjs.org/docs/code-splitting.html#route-based-code-splitting
它应该根据当前路由动态延迟加载路由组件(ModuleOne 或 ModuleTwo)及其依赖项。
然而,代码拆分似乎不起作用,所有内容都包含在一个包中。
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index',
output: {
filename: '[name].bundle.js',
chunkFilename: '[name].bundle.js',
path: path.resolve(__dirname, '../dist'),
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'awesome-typescript-loader',
exclude: /node_modules/,
}
],
},
resolve: {
modules: ['node_modules', path.resolve(__dirname, '../src')],
extensions: ['.js', '.jsx', '.ts', '.tsx'],
}
};
App.tsx
import * as React from 'react';
import { HashRouter as Router, Link, Route, Switch } from 'react-router-dom';
import * as styles from './App.scss';
const LazyModuleOne = React.lazy(() => import('../modules/ModuleOne/ModuleOne'));
const LazyModuleTwo = React.lazy(() => import('../modules/ModuleTwo/ModuleTwo'));
const App = () => (
<Router>
<div className={styles.wrapper}>
<nav>
<Link to="/">Start</Link>
<Link to="/module-one">Module One</Link>
<Link to="/module-two">Module Two</Link>
</nav>
<main>
<React.Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route path="/module-one" component={LazyModuleOne} />
<Route path="/module-two" component={LazyModuleTwo} />
</Switch>
</React.Suspense>
</main>
</div>
</Router>
);
export default App;
ModuleOne.tsx
import * as React from 'react';
import * as _ from 'lodash';
import { RouteComponentProps } from 'react-router';
const apples = _.fill([1,2,3], 'apple');
const ModuleOne: React.FC<RouteComponentProps> = () => (
<div>
<div>ModuleOne</div>
<div>There are {apples.length} apples</div>
</div>
)
export default ModuleOne;
ModuleTwo.tsx
import * as React from 'react';
import * as R from 'ramda';
import { RouteComponentProps } from 'react-router';
const cherries = [1,2,3];
const ModuleTwo: React.SFC<RouteComponentProps> = () => (
<div>
<div>ModuleTwo</div>
<div>There are {R.length(cherries)} cherries</div>
</div>
)
export default ModuleTwo;
演示:
有谁知道为什么基于路由的代码拆分无法按预期工作?
我的 React 版本是 16.4.0,可以使用!
我和你唯一的区别:
我正在使用 BrowserRouter。 你使用了 HashRouter。
我找到了解决方案。这与 TypeScript
相关。我需要设置:
{
"compilerOptions": {
"module": "esnext",
},
}
而不是 commonjs
。
现在代码拆分工作正常。