为什么要做dynamic import?

dynamic import不知道为什么有很多叫法,什么按需加载,懒加载,Code Splitting,代码分页等。
总之,就是在SPA,把JS代码分成N个页面份数的文件,不在用户刚进来就全部引入,而是等用户跳转路由的时候,再加载对应的JS文件。
这样做的好处就是加速首屏显示速度,同时也减少了资源的浪费。

为什么选择 webpack 3?

  • 更高的性能
  • 有scope hosting功能,不再需要rollup来处理代码冗余
  • 可与react-router结合,更优雅的做dynamic import
  • 最重要的一点是,我正经学webpack的时候3已结出了- -

完整的 react spa 项目地址

GitHub项目地址

这个一个完整的项目,这节相关的内容可在router/routerMap.jsx中找到。

第一步:安装 babel-plugin-syntax-dynamic-import

babel用的是babel-env,使用方法可以去babel官方学习,实践可看我项目的源代码。

npm i -D babel-plugin-syntax-dynamic-import 以后, 在.babelrc文件的plungins中加上"syntax-dynamic-import"

第二步:安装 react-loadable

npm i -S react-loadable 以后,我们就能愉快得做dynamic import了。

第三步: 编辑routerMap


import React from 'react';
import { HashRouter as Router, Route, Switch } from 'react-router-dom';
import createHistory from 'history/createBrowserHistory';
const history = createHistory(); import App from 'containers'; // 按路由拆分代码
import Loadable from 'react-loadable';
const MyLoadingComponent = ({ isLoading, error }) => {
// Handle the loading state
if (isLoading) {
return <div>Loading...</div>;
}
// Handle the error state
else if (error) {
return <div>Sorry, there was a problem loading the page.</div>;
}
else {
return null;
}
};
const AsyncHome = Loadable({
loader: () => import('../containers/Home'),
loading: MyLoadingComponent
});
const AsyncCity = Loadable({
loader: () => import('../containers/City'),
loading: MyLoadingComponent
});
const AsyncDetail = Loadable({
loader: () => import('../containers/Detail'),
loading: MyLoadingComponent
});
const AsyncSearch = Loadable({
loader: () => import('../containers/Search'),
loading: MyLoadingComponent
});
const AsyncUser = Loadable({
loader: () => import('../containers/User'),
loading: MyLoadingComponent
});
const AsyncNotFound = Loadable({
loader: () => import('../containers/404'),
loading: MyLoadingComponent
}); // 路由配置
class RouteMap extends React.Component {
render() {
return (
<Router history={history}>
<App>
<Switch>
<Route path="/" exact component={AsyncHome} />
<Route path="/city" component={AsyncCity} />
<Route path="/search/:category/:keywords?" component={AsyncSearch} />
<Route path="/detail/:id" component={AsyncDetail} />
<Route path="/user" component={AsyncUser} />
<Route path="/empty" component={null} key="empty" />
<Route component={AsyncNotFound} />
</Switch>
</App>
</Router>
);
// 说明
// empty Route
// https://github.com/ReactTraining/react-router/issues/1982 解决人:PFight
// 解决react-router v4改变查询参数并不会刷新或者说重载组件的问题
}
} export default RouteMap;

大功告成

我们可以运行webpack,然后就能看到效果(图仅为dev环境,build才会再打包一个vendor.js,为什么要有vendor.js,请见devDependencies和dependencies的区别 >>

参考文章

Code Splitting in Create React App

Q&A

有同学表示,我的方法做页面分离并没有什么好处,因为每个页面都依赖了三方库的代码,所以其实页面有很多冗余代码,能想到这点很棒,已经开始有架构思维了。不过,注意这个想法在dev环境下,这个同学是对的。

那到了build环境,或者说到了发布环境,又是怎么样的呢?的确,这篇文章我没有提到,请见我的另一篇文章devDependencies和dependencies的区别。这篇文章主要解释了npm的package.json中devDependencies和dependencies区别是什么。

看完以后,我们就可以知道,为什么我之前说“注意这个想法在dev环境下,这个同学是对的”了。因为,我们npm run build以后,webpack会把三方包打包到vendor.js文件,页面逻辑代码不会牵涉其中,每个页面都会引用vendor.js这个文件,这样的话,就不会出现重复引入冗余代码的情况了。

来源:https://segmentfault.com/a/1190000011128817

webpack v3 结合 react-router v4 做 dynamic import — 按需加载(懒加载)的更多相关文章

  1. [Web 前端] React Router v4 入坑指南

    cp from : https://www.jianshu.com/p/6a45e2dfc9d9 万恶的根源 距离React Router v4 正式发布也已经过去三个月了,这周把一个React的架子 ...

  2. [React Router v4] Render Multiple Components for the Same Route

    React Router v4 allows us to render Routes as components wherever we like in our components. This ca ...

  3. React Router V4发布

    React Router V4 正式版发布,该版本相较于前面三个版本有根本性变化,遵循 Just Component 的 API 设计理念. 本次升级的主要变更有: 声明式 Declarative 可 ...

  4. [React Router v4] Intercept Route Changes

    If a user has entered some input, or the current Route is in a “dirty” state and we want to confirm ...

  5. [React Router v4] Redirect to Another Page

    Overriding a browser's current location without breaking the back button or causing an infinite redi ...

  6. [React Router v4] Conditionally Render a Route with the Switch Component

    We often want to render a Route conditionally within our application. In React Router v4, the Route ...

  7. [React Router v4] Render Catch-All Routes with the Switch Component

    There are many cases where we will need a catch-all route in our web applications. This can include ...

  8. [React Router v4] Render Nested Routes

    With React Router v4 the entire library is built as a series of React components. That means that cr ...

  9. [React Router v4] Parse Query Parameters

    React Router v4 ignores query parameters entirely. That means that it is up to you to parse them so ...

随机推荐

  1. 洛谷—— P1503 鬼子进村

    https://www.luogu.org/problemnew/show/P1503 题目背景 小卡正在新家的客厅中看电视.电视里正在播放放了千八百次依旧重播的<亮剑>,剧中李云龙带领的 ...

  2. Jenkins解决Host key verification failed

    1.在没有做任何操作时,是这样报错的 a.在任务中配置远程执行命令 rsync -raz --delete --progress  target/testweb-v1.1.jar  root@10.0 ...

  3. Linux下挂载指定分区下的某个文件夹到指定目录(mount)

    # 挂载 mount --bind olddir newdir # 卸载 umount newdir 参考: http://www.cnblogs.com/dabaopku/archive/2010/ ...

  4. windows pipe

    管道分为 匿名管道 和 命名管道 . 1.匿名管道仅仅能在父子进程间进行通信.不能在网络间通信,并且传输数据是单向的.仅仅能一端写,还有一端读. 2.命令管道能够在随意进程间通信.通信是双向的,随意一 ...

  5. 安装惠普M1136打印机一直处于“新设备已连接”状态怎么办?

    百度的答案是从控制面板的添加打印机入手,我试了遇到找不到设备的问题. 其实问题的原因是在安装驱动时一直把打印机到电脑的USB插着.我的解决方案是: 1.点击M1130MFP_M1210MFP开始安装, ...

  6. Android自己定义ViewGroup打造各种风格的SlidingMenu

    看鸿洋大大的QQ5.0側滑菜单的视频课程,对于側滑的时的动画效果的实现有了新的认识,似乎打通了任督二脉.眼下能够实现随意效果的側滑菜单了.感谢鸿洋大大!! 鸿洋大大用的是HorizontalScrol ...

  7. 如何用迅雷下载在网页中的Flash动画或课件

    对于框架网页而言,看地址栏可以发现后缀不是SWF,就是说该网站没有直接把Flash给你,右击该Flash也没有下载选项.   此时虽然右下角是Flash,但是左边和上面网页部分还是正常的元素,右击这些 ...

  8. Linux mm相关的问题

    [S]为什么High MEM是从896M開始的? As the running kernel needs these functions, a region of at least VMALLOC_R ...

  9. 使用Nightwatch.js做基于浏览器的web应用自动测试

    1        安装 1.1   安装Node.js 在http://nodejs.org/ 上下载适合本机系统的安装包运行安装,注意安装选项中选择npm tool以用于后续依赖包的安装. 1.2  ...

  10. 【Sprint3冲刺之前】项目完成时间表

    Sprint2冲刺成果——项目完成时间表 项目完成时间表 经过Sprint2小组总结会议的探讨,我们决定一起约定项目alpha版本,beta版本,release版本的发布时间,发布形式及预计完成效果 ...