搭建Typescript+React项目模板(4) --- 项目打包

相关文章和阅读顺序

搭建Typescript+React项目模板(1) --- 项目初始化
搭建 Typescript+React 项目模板 (2) --- 提升开发体验
搭建 Typescript+React 项目模板 (3) --- 整理项目和杂项
搭建 Typescript+React 项目模板 (4) --- 项目打包
搭建 Typescript+React 项目模板 (5) --- 团队规范

文章已同步更新到掘金专栏(https://juejin.im/user/5a77c815f265da4e9518bebc/posts)

项目地址

前言

经过前面的初始化,提升开发体验和集成了一堆工具,调整了项目结构等等之后,我们是时候考虑进行项目打包了。
在这篇博客中,我们不考虑开发环境和生产环境的配置分别,我们只看打包需要进行的配置项,所以我们需要做的如下:

  1. 添加打包路径工具
  2. 添加打包命令
  3. 进行css和js分离
  4. 修改html-webpack-plugin配置项
  5. 添加react-loadablereact-router,进行代码分离和按需加载
  6. 添加optimization,进行第三方库代码分离
  7. 进行代码压缩
  8. 关于externals

添加打包命令

我们先去webpack.config.js中观察一下output这个配置项:

image.png

该配置项指定了打包路径和打包后的js文件名,在webpack的配置项中,output是必须有的。
接着我们去到package.json中在script中添加打包命令build,该命令引用我们的webpack.config.js配置文件:
image.png

之后试试运行npm run build,会发现已经将项目打包出来了:
image.png

添加打包路径工具

在上一步中,我们已经知道打包出来的文件位于根目录下的dist文件夹中,所以这个路径工具的添加指向dist文件夹:
我们去到build/utils.js文件中,添加如下代码:

image.png

以后指定打包文件存放路径的时候就可以直接使用这个工具进行指定。

分离css文件

在上面打包的结果中,我们会发现只有一个app.js文件,而实际上我们是有写css样式的,但是现在的却并没有这个css文件,这是因为webpack将所有的资源(包含js, css等等)都看成是chunk,然后一起打包进一个文件中,这样会导致打包出来的js文件体积巨大,从而拖累页面的加载速度。

  1. webpack 4+版本中,我们可以使用mini-css-extract-plugin进行css代码的分离,所以首先安装它npm install -D mini-css-extract-plugin
  2. 然后我们到build/plugins.js中添加这个插件:
    image.png
  3. 最后需要注意,之前在提升开发体验这一章中有提到过一点,style-loader用于将css-loader编译出来的代码转为js代码并写入js文件中,所以在这里,我们需要用mini-css-extract-plugin中的loader去替换掉style-loader,让它写入单独的css文件而不是js文件中:
    我们去到build/rules/styleRules.js中,将原本的style-loader全都替换成mini-css-extract-plugin的loader(这一步可以进行开发环境和生产环境的区分,在文章中不进行区分):
    image.png

    image.png
  4. 经过上面的步骤,我们可以打包进行测试:
    运行npm run build可以发现打包结果中css文件已经进行了分离:
    image.png

    而在打包出来的index.html中也可以发现这个css文件被引入了:
    image.png
  5. 最后我们再在打包路径中将打包出来的js文件用js文件夹包裹起来即可:


    image.png

    image.png

修改html-webpack-plugin配置项

这一步主要用于压缩打包出来的index.html文件,但是单页面应用的话html内容其实不多,所以做不做也差不多,在本文章中也只是做个介绍:

  1. 首先在html-webpack-plugin中利用的是html-minifier来做压缩工作的,所以详细配置点击进去看即可,常用的如下:
    image.png
  2. 第二个需要提一下则是inject这个配置项,该项指定资源如何注入,我们直接使用默认的true即可,他会将js资源注入到<body>标签的底部,如果要注入到头部填写head即可

添加react-loadablereact-router,进行代码分离和按需加载

这一步和下一步都是在进行代码的拆分,考虑的是如果所有文件都塞进一个js文件中,会导致这个js文件体积臃肿,而单页面应用的所有构建又是依赖于这个js文件,所以需要进行代码分离,只加载当前页面需要构建的js文件。
通常来说,我们会根据react-router分的页面来进行代码分离,再用react-loadable进行分割出来的代码的异步加载(当然你也可以将所有组件都进行代码分离然后异步加载)。
所以在这里我们先利用react-router分两个页面homepage出来:

  1. 首先我们安装react-router:
    npm install -S react-router-dom,然后在src/containers/views中新建HomePage组件:
    image.png

    image.png

    image.png
  2. 接着安装react-loadable:
    npm install -S react-loadable, 然后在src/containers/shared中新建App组件:
    image.png

    之后在里面的index.tsx中引用react-routerreact-loadable进行组件按需加载:
    当然不要忘了使用react-hot-loader:
    image.png

    这一步需要注意的是,Loadable这个函数中的loading参数是必须有的,至于如何使用可以自行参考react-loadable的github链接。
  3. 这个时候去到页面看一下:
    /路径下,没有加载page.js这个文件,而切换到/page路径则会加载page.js文件,这个时候按需加载就完成了:
    image.png

    image.png
  4. 最后我们观察一下打包后的js文件可以发现已经进行了分离:


    image.png

会用optimization进行第三方库代码分离

optimization是webpack4+版本中新出的配置项,这个配置项的功能主要是进行代码压缩,优化。
在本节中,我们需要将用到的处于node_modules中的第三方代码进行分离,在这里主要用到的是两个配置项optimization.runtimeChunkoptimization.splitChunks,其中runtimeChunk用于生成维系各各代码块关系的代码,splitChunks则用于指定需要进行分块的代码,和分块后文件名。

  1. 我们去到build目录下,新建optimization.js,并添加如下代码:
    image.png

    然后在webpack.config.js中引入这个配置:
    image.png
  2. 最后我们打包试试看可以发现第三方代码都被打包进vendor.js文件中了:
    image.png

    你可以通过比对在添加optimization之前和之后打包出来的app.js文件来看出效果。

进行代码压缩

在这一步中,我们主要是做js和css的代码压缩和优化

  1. 在上面阶段中,我们打包出来的js代码是已经经过压缩的:
    image.png

    所以在这个阶段我们可以利用uglifyjs-webpack-plugin进行一些压缩优化:
    首先我们需要安装npm install -D uglifyjs-webpack-plugin,然后去到build/optimization.js中添加如下代码即可,具体的优化见代码:
    image.png

    PS: 这里有一个点需要注意,在uglifyjs-webpack-plugin这个插件中,如果是2.x版本的话是不支持es6规范的,所以建议安装1.x版本,而我这里的版本是:
    image.png
  2. 然后我们进行css代码的压缩,这里需要使用到optimize-css-assets-webpack-plugin插件:npm install -D optimize-css-assets-webpack-plugin
    我们先去Home组件中随意添加一个样式并使用它:
    image.png

    image.png

    然后再去到build/optimization.js添加如下代码:
    image.png

    具体的插件使用方式可以自行上github查看该插件。
    最后查看打包出来后的css代码:
    image.png

到现在压缩代码步骤也做完了,最后将介绍一下webpack.externals这个选项。

关于externals

webpack.externals配置项用于在构建过程中忽略一些常用包的集成,从而降低构建时间和打包后的包大小,它的配置也很简单,在本章中只做简单介绍:
在本项目中,我们可以将reactreact-dom添加进externals中,然后在html模板中引入它们的外部链接:

  1. 我们先去到webpack.config.js中,添加externals选项,并且把reactreact-dom添加进去:
    image.png

    这个配置项接收的是一个对象(其他形式请自行查阅webpack文档),对象的键是指webapck在获取这个模块时候require时候的参数,而对应的值则是标明你打算将这个模块挂载的变量名,这里是挂载在window对象中的。
  2. 去到build/tpl/index.html中,引入cdn中reactreact-dom的链接:
    image.png
  3. 重启项目,可以发现在npm run dev中能够正常使用,并且也已经引入了两者的外部资源:
    image.png
  4. 最后我们来对比一下打包后模块占用情况:


    不使用externals

    使用externals

    再来对比一下两者打包出来的包体积大小:


    不使用externals

    使用externals
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容