龙空技术网

在 Webpack 中执行代码分割

爱音乐的程序员小新人 156

前言:

今天我们对“js分割文件”都比较讲究,我们都想要分析一些“js分割文件”的相关文章。那么小编在网摘上搜集了一些对于“js分割文件””的相关资讯,希望我们能喜欢,各位老铁们一起来了解一下吧!

有三种常用的代码分离方法:

入口起点:使用 entry 配置手动地分离代码。防止重复:使用 CommonsChunkPlugin 去重和分离 chunk。动态导入:通过模块的内联函数调用来分离代码。

1、入口起点

这是迄今为止最简单、最直观的分离代码的方式。不过,这种方式手动配置较多

webpack.config.js

const path = require('path');const HTMLWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: { index: './src/index.js', another: './src/another-module.js' }, plugins: [ new HTMLWebpackPlugin({ title: 'Code Splitting' }) ], output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist') }};

这将生成如下构建结果

Hash: 309402710a14167f42a8Version: webpack 2.6.1Time: 570ms Asset Size Chunks Chunk Names index.bundle.js 544 kB 0 [emitted] [big] indexanother.bundle.js 544 kB 1 [emitted] [big] another [0] ./~/lodash/lodash.js 540 kB {0} {1} [built] [1] (webpack)/buildin/global.js 509 bytes {0} {1} [built] [2] (webpack)/buildin/module.js 517 bytes {0} {1} [built] [3] ./src/another-module.js 87 bytes {1} [built] [4] ./src/index.js 216 bytes {0} [built]

正如前面提到的,这种方法存在一些问题:

如果入口 chunks 之间包含重复的模块,那些重复模块都会被引入到各个 bundle 中。这种方法不够灵活,并且不能将核心应用程序逻辑进行动态拆分代码。

2、防止重复

CommonsChunkPlugin 插件可以将公共的依赖模块提取到已有的入口 chunk 中,或者提取到一个新生成的 chunk。让我们使用这个插件,将之前的示例中重复的 lodash 模块去除:

webpack.config.js

const path = require('path');+ const webpack = require('webpack'); const HTMLWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: { index: './src/index.js', another: './src/another-module.js' }, plugins: [ new HTMLWebpackPlugin({ title: 'Code Splitting'- })+ }),+ new webpack.optimize.CommonsChunkPlugin({+ name: 'common' // 指定公共 bundle 的名称。+ }) ], output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist') } };

这里我们使用 CommonsChunkPlugin 之后,现在应该可以看出,index.bundle.js 中已经移除了重复的依赖模块。需要注意的是,CommonsChunkPlugin 插件将 lodash 分离到单独的 chunk,并且将其从 main bundle 中移除,减轻了大小。执行 npm run build 查看效果:

Hash: 70a59f8d46ff12575481Version: webpack 2.6.1Time: 510ms Asset Size Chunks Chunk Names index.bundle.js 665 bytes 0 [emitted] indexanother.bundle.js 537 bytes 1 [emitted] another common.bundle.js 547 kB 2 [emitted] [big] common [0] ./~/lodash/lodash.js 540 kB {2} [built] [1] (webpack)/buildin/global.js 509 bytes {2} [built] [2] (webpack)/buildin/module.js 517 bytes {2} [built] [3] ./src/another-module.js 87 bytes {1} [built] [4] ./src/index.js 216 bytes {0} [built]

以下是由社区提供的,一些对于代码分离很有帮助的插件和 loaders:

ExtractTextPlugin: 用于将 CSS 从主应用程序中分离。bundle-loader: 用于分离代码和延迟加载生成的 bundle。promise-loader: 类似于 bundle-loader ,但是使用的是 promises。

CommonsChunkPlugin 插件还可以通过使用显式的 vendor chunks 功能,从应用程序代码中分离 vendor 模块。

3、动态导入

当涉及到动态代码拆分时, 一般使用使用webpack提供的符合 ECMAScript 提案 的 import() 语法。

new Vue({

el: '#app', components: { AsyncComponent: () => import('./AsyncComponent.vue') }});

实施代码分割并不难,难在搞清楚在什么时候、什么地方进行。

Vue.js 单页应用进行代码分割有三种思路:

按页面分割使用折叠按条件分割

1. 按页面

按页面来进行代码分割,是最明显的一种方式。

如果能确保每个单文件组件代表一个页面,如 Home.vue, About.vue 以及 Contact.vue,那么我们就可以使用 Webpack 的 "动态导入" 函数 (import) 来将它们分割至单独的构建文件中。之后后,当用户访问一个新页面的时候,Webpack 将异步加载该请求的页面文件。

如果用到了 vue-router,由于页面已经分割成了单独的组件,实施起来会非常方便。

const Home = () => import(/* webpackChunkName: "home" */ './Home.vue'); const About = () => import(/* webpackChunkName: "about" */ './About.vue'); const Contact = () => import(/* webpackChunkName: "contact" */ './Contact.vue'); const routes = [ { path: '/', name: 'home', component: Home }, { path: '/about', name: 'about', component: About }, { path: '/contact', name: 'contact', component: Contact } ];

代码编译完成后,通过查看生成的统计数据得知:每个页面都有自己单独的文件,同时有多出来一个名为 build_main.js 的打包文件。里面包含一些公共的代码以及逻辑,用来异步加载其它文件,因此它需要在用户访问路由之前加载完成。

2. 折叠

“折叠” 是指页面初次加载时,视图的不可见部分。用户通常会花费 1~2 秒来浏览可视区域,特别是第一次访问网站的时候(可能更久),之后才开始向下滑动页面。

这个时候,可以异步加载剩余的内容。

3. 条件展示内容

代码分割另一种比较好的备选方式,是按条件展示。比如:模态框、标签页、下拉菜单之类。

如果我们需要一个模态框,给模态框设置 v-if 属性,绑定了 show 变量。一方面用来控制模态框是否显示,同时也决定了是否应该渲染模态框组件。当页面加载的时候,它的值为 false,模态框的代码只有当它显示的时候才会被加载。如果用户永远不打开这个模态框,这部分代码就永远不会被下载。缺点是,可能会增加很小的用户体验成本:用户点击按钮后,需要等待代码文件下载完成。

标签: #js分割文件