系列 字符串数组 我们 justify 帮助 babel 强调 ctrl+
很久没有发文章了,但是强调一点,大~熊同学最近可没闲着。学习算法,复习计算机网络,也顺便学习了一下 webpack,看了看操作系统(没办法,都没学,要是不学连实习笔试都过不了,伤心~~)。本来比较纠结是写关于算法的文章呢还是关于 webpack 的呢。最终决定写关于 webpack 的,一方面,虽然刚刚开始学习 webpack,但是他的特性让人感觉非常爽,然我有一种想分享的冲动; 另一方面,算法要写公式,这个编辑器貌似不太好编辑,截图也比较麻烦。废话不说了,这篇文章介绍 webpack 的四个核心配置项。我写的不好,你可以参考:中文文档、英文文档。当然看看我写的也是可以的。
(1)建立项目目录:mkdir WP
(2)进入项目目录:cd WP
(3)用 npm init 建立 package.json 文件(随便起一个名字,一路回车就好)
(4)安装 webpack:npm install --save-dev webpack
(5)测试是否安装成功,法现 webpack -v 找不到命令,直接在 package.json 的 scripts 加上 "webpack": "webpack",然后运行 npm run webpack -v 结果正确
(6)建立源文件目录:mkdir src
(7)用编辑器打开项目:subl .
至此,准备工作完成,我们得到的的项目目录和 package.json 文件如下所示:
(写了半天,发现插入一段代码后不能到下一行了,按了几次 CTRL+Z, 居然回到这里了,真无语,再来一次)
为了测试先建立如下项目结构
各个文件内容如下:
- //index.jsimport A from './js/test.js';
- function hello(){
- console.log("hello");
- console.log(A);
- }
- hello();
- //index.htmlforwebpack study
- 祝大家发财
- //webpack.config.jsconst path = require("path");
- module.exports = {
- entry:"./src/index.js",
- output:{
- path:path.resolve(__dirname,'dist'),
- filename:"bundle.js"
- },
- // module:{},
- // plugins:{}}
直接终端运行一下:
打开项目看一下:
发现生成了一个 dist 目录,里面多了一个 bundle.js 的文件,查看 bundle.js 发现下面有我们 index.js 中的内容(这个是之前截的图,有点不一致了)。假如我们在 index.js 声明依赖会如何。先在 js 目录下建一个 test.js 文件,内容如下:
- const A = "大~熊最帅!";
- export
- default A;
然后在 index.js 中声明对它的依赖
- import A from './js/test.js';
- function hello(){
- console.log("hello");
- console.log(A);
- }
- hello();
打包一下:
发现生成了一个 bundle.js, 然后有两个文件。查看 bundle.js 会发现,test.js 中的内容也加到里面了。下面在 index.html 中加上:
- <script type="text/javascript" src="../dist/bundle.js">
- </script>
预览如图:
发现引入一个 bundle.js 就相当于 index.js 和 test.js 都进来了,可以正常使用。 通过这样一个简单的例子相信你已经感受到了 webpack 的强大之处,下面详细介绍 entry 和 output 两个属性的多种用法。
(1)entry:entry 指定打包入口,可以是一个字符串,也可以是一个字符串数组,还可以是一个对象。
A、指定一个字符串的情况上面已经提到了,它适用于单入口的情况。
B、指定一个字符串数组。
在 src 目录建立 index2.js,并修改配置文件,见下:
- //index2.js
- function index2(){
- console.log("this is index 2");
- }
- index2();
- //webpack.config.js
- const path = require("path");
- module.exports = {
- entry:["./src/index.js","./src/index2.js"],
- output:{
- path:path.resolve(__dirname,'dist'),
- filename:"bundle.js"
- },
- // module:{},
- // plugins:{}
- }
打包一下
可以发现我们生成的内容有点不一样,3 后面有个 multi,这里从多个入口触发检查依赖生成了一个 chunk。当你的 index2.js 和 index.js 是互不依赖,而你又想把他们打包到一起,那么这种方式正是你需要的。的。下面检查一下生成的 bundle.js 是什么样子。
C:entry 值为一个对象的情况
第一种情况,只有一个键值,这和 A 情况是一样的。
- const path = require("path");
- module.exports ={
- entry:{ main:"./src/index.js"
- },
- output:{
- path:path.resolve(__dirname,'dist'),
- filename:"bundle.js"
- },
- // module:{},
- // plugins:{}}
第二种情况,多个键值对。
- const path = require("path");
- module.exports ={
- entry:{ main:"./src/index.js",
- second:"./src/index2.js"
- },
- output:{
- path:path.resolve(__dirname,'dist'),
- filename:"[name]-bundle.js"
- },
- // module:{},
- // plugins:{}}
注意我这里改了一下 output, 否则报如下错误:
按照我的修改做结果是:
可以发现生成了两个 chunk,文件名字分别为 main-bundle.sj 和 second-bundle.js,chunk 名字分别为 main、second。如果要将从多个入口文件打包的东西放到不同的文件,那么此款适合你。关于那个 output 是什么意思,马上开讲。
(2)output 基本用法
output 有很多属性可用,这里列举几个最最常用的属性。
[name]: 表示你在 entry 指定入口时的那个键,上面的是 main 和 second
[hash]: 表示当次打包的一个标识,修改之后在打包会变化,一次打包的不同 chunk 的值相同
[chunkhash]: 表示每一个 chunk 的唯一标识,显然不同 chunk 是不一样的,当某个 chunk 里的东西改变时二次打包他的 chunkhash 才会改变,否则保持不变
[id]: 表示 chunk 的编号,上面是 0 和 1
以下重点看看那 hash 和 chunkhash
修改 index.js 再打包
发现我们只改了一个 index.js, 另外一个的 hash 也变了。
下面将配置给为 [chunkhash]
- const path = require("path");
- module.exports = {
- entry:{
- main:"./src/index.js",
- second:"./src/index2.js"
- },
- output:{
- path:path.resolve(__dirname,'dist'),
- filename:"[name]-[chunkhash]-bundle.js"
- },
- // module:{},
- // plugins:{}}
打包一次然后修改 index.js 再打包一次结果如下:
发现只有我们修改的文件对应的 chunk 的 chunkhash 发生了改变,那个 second 并没有改变。使用 chunkhash 可以有效利用缓存,不用全部重新下载。比如,你上线了一个应用,已经被很多用户访问,这时在他们的浏览器有缓存,如果你修改了一个文件,再次上线,如果用 chunkhash,只有你该过的那个 chunk 的文件名会变,其他的文件缓存还可以用,加快了加载速度。如果用 hash 的话,所有的文件名都会改变,所有文件都得重新下载,这是不好的。
你可能已将注意到了,src 中的 html 文件并没有到 dist 目录中去。如果我们直接在 dist 中建立 html 文件,由于我们的 chunk 的文件名是变化的,每一次改变都要重新调整引入。下面介绍 HtmlWebpackPlugin 这款插件来解决这个问题,以此了解 plugins 配置项。
(1)安装
(2)配置
- const path = require("path");const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports= {
- entry:{
- main:"./src/index.js",
- second:"./src/index2.js"
- },
- output:{
- path:path.resolve(__dirname,'dist'),
- filename:"[name]-[chunkhash]-bundle.js"
- },
- // module:{},
- plugins:[
- new HtmlWebpackPlugin({
- template:"./src/index.html"
- })
- ]}
(3)打包
发现生成了一个 index.html 文件。
(4)看效果
这里有一个文件找不到,是因为我们的 src 文件夹下的 index.html 引入了一个 bundle.js 但是现在没有这个东西了,去掉就好。
HtmlWebPlugin 插件还有比较多的配置项,也还具备很强大的功能,详情见官网,这里只是抛砖引玉。
module 配置项是用来指定 loader 的,loader 实质上是用来对我们的资源进行预处理的工具,便于 webpack 将他们当成模块。下面以 babel-loader 为例讲解这个配置项。
(1)安装(截图时还没装完)
(2)配置
- const path = require("path");
- const HtmlWebpackPlugin = require('html-webpack-plugin');
- module.exports = {
- entry:{
- main:"./src/index.js",
- second:"./src/index2.js"
- },
- output:{
- path:path.resolve(__dirname,'dist'),
- filename:"[name]-[chunkhash]-bundle.js"}, module:{
- rules: [
- {
- test: /\.js$/,
- exclude: /(node_modules|bower_components)/,
- use: 'babel-loader',
- options: {
- presets: ['es2015']
- }
- }
- ]
- },plugins:[new HtmlWebpackPlugin({
- template:"./src/index.html"
- })
- ]
- }
(3)打包
(4)看效果(这里从打包后生成的文件看效果)
看到第 79 行,我们源文件是 const 但是这里变成了 var。babel-loader 的工作就是将新标准的新特性转换成浏览器支持的写法,因为这些新特性可能还不被浏览器支持,有了这样的转化,我们就可以肆无忌惮(这个词用的很棒)的使用新特性了。比如这里我们用到了 es6 的新特性 const,babel 帮我们转成了 var,这样所有浏览器都支持了。
我们来看一下 module 这个配置。这个对修有一个 rules 属性(2.X 版本),rules 是一个数组,里边可以定义一系列的处理规则,每一个是一个对象。每一个规则包含一些配置项,核心有 test 指明对什么文件应用这个规则,use 指定处理的 loader 名字,如果有多个 loader 可以是一个数组。options 是提供一些配置项。还有像 exclude 等等等诸多配置项,你可以去官网查阅,这里不作展开,点到为止。
webpack 是一款非常非常强大的模块化工具,她彻底颠覆了传统的局部思维模式,而是将我们项目看作一个整体,有效的帮助我们解决各种依赖问题,解决各种资源的转换问题。本文用几个简单的例子讲解了 webpack 的四大核心配置项的基本用法,仅作抛砖引玉之用,webpack 十分强大,有丰富的 loader 和 plugin 可供我们使用,本文介绍的内容只是其冰山一角。更多信息请参考官网。
最后,如果你觉得大~熊同学写的文章对你有所启发,请关注一下,他和他的哆啦 A 梦都会很开心的!!!
参考:
webpack 你值得拥有 - 从四个核心配置谈起
来源: http://www.bubuko.com/infodetail-2043235.html