总结:激励是,默认情况下最重要的东西会放在public中,其中包含启动应用程序的依赖模块、模块的依赖项以及文件的版本号等信息。
之前写过一篇关于如何使用webpack的文章:webpack单页应用实践,也写了一个小型的单页应用项目放在github上。 正好前段时间公司用webpack做一个项目。 该项目并不大,并且基于单页应用程序。 而且上线之后,发现了一些问题。 本来还有一些地方需要优化和改进。
这篇关于webpack单页应用实践的文章已经基本满足了我们的需求。 例如,我们已经实现了以下功能:
将 css 与 js 分开
使用loader加载css、图片等
使用插件生成html,方便手动引用版本号变化的文件
配置公共js
js文件按需加载
配置开发环境
压缩js、css、html
给css、js、图片、字体等添加版本号
编译完成后,手动打开浏览器
热替换
使用代理结合前端服务开发
编译时区分开发环境、生产环境和热替换环境
合并配置文件
清除发布目录
看起来不错,好像很早之前就已经实现了,到了生产环境还是存在问题。 下面还有几个优化(下面还是结合这个项目)。
优化-公共js版本号会变化的问题
项目上线之前我并没有注意到这个问题。 项目上线后,需求发生了变化。 当我更改其他js文件时,发现打包发布后公共js的版本号发生了变化。 最后检测确实是公共js。 内容发生了变化,所以对应的版本号也发生了变化。 原因是webpack默认会把最重要的东西放在public js中,其中包括webpack启动应用程序的依赖关系、模块之间的依赖关系、文件版本号等信息。 所以一旦任何js文件发生改变,都会反映在公共js中。 例如,我们通过webpack构建后生成一个这样的文件:
我们看一下common.js一般都包含哪些内容(截取了一小部分):
公共js版本号改变的问题在github上已经讨论了一段时间(点击这里)webpack页面优化,不过之前没有关注。 有人用webpack-md5-hash插件实现过,发现比较麻烦。 最后,我觉得webpack贡献者实现的方法非常简单,而且不需要额外的插件,并且很好地集成在新版本的webpack中。 而且提供的demo过于简单,所以我们在项目过程中还是要注意一些问题。 例如使用‘热替换’时会报错。 所以我们需要做出一些改变。 我们之前只需要配置一下公共js即可:
// webpack.config.js ... plugins:[ // 会把 ‘entry’ 定义的 common 对应的两个js 打包为 ‘common.js’ new webpack.optimize.CommonsChunkPlugin("common", "js/[name].js", Infinity), ] ...
改成:
// webpack.config.js ... new webpack.optimize.CommonsChunkPlugin( devServer ? {name: "common", filename: "js/common.js"}: {names: ["common", "webpackAssets"]} ), ...
注意: ‘devServer’ 是一个标识变量,代表‘热替换’ ,如有疑惑看上一篇配置变量标识
更改这些设置后,common.js 将不会以热替换模式进行处理。 如果是开发模式或者发布模式,会从common.js中提取出各个文件的版本号等重要信息,放到‘webpackAssets.js’文件中(名称可以自定义)。 生成的文件如下,还会多一个文件,这个文件只有几kb:
更改为这些做法后,一旦其他文件发生更改,都会反映在 webpackAssets.js 文件中。 项目的发布和升级只需要额外升级这个文件即可webpack页面优化,不需要升级公共js。 这种优化对于处理缓存问题特别有帮助。
优化-设置模块目录
如果项目比较小,不设置webpack需要的模块目录也没关系,而且通常随着项目变大,webpack会发现很多无用的文件。 这时候就需要设置module目录来提高webpack编译的速度。 即设置resolve.root属性。 还有另一个属性称为 moduleDirectories。 两者的区别可以在这里找到。 resolve.root接收到的参数是添加到node_modules文件中的绝对路径。 我们在之前的webpack.config.js中降低了这个配置项:
// webpack.config.js ... resolve:{ root: [ path.resolve("./node_modules") ], ... } ...
这样设置后,webpack编译速度将大大提高,并且不会再次搜索每个文件夹。
发表评论