webpack说容易也容易,说难也难,主要还是看个人,想学到什么样的程度,很多公司可能要求仅仅是会用就行,但是也有一些公司要求比较高,要懂一些底层的原理,所以还是要花一些时间的,看个人需求。这篇仅仅是做了一些总结,都是来自官网,便于复习。

一,先理解webpack的概念:

官网上:webpack 是一个现代 JavaScript 应用程序的模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成少量的 bundle - 通常只有一个,由浏览器加载。

这里补充一下,webpack和gulp的差异:

gulp是一种前端自动化构建工具,task runner,它的核心功能是:

1,task的定义和组织

2,基于文件的stream构建

3,插件体系

webpack是module bundler,模块打包器,核心功能是:

1,按照模块的依赖构建目标文件

2,loader 体系支持不同的模块

3,插件体系提供更多额外的功能

原作者链接:https://www.zhihu.com/question/45536395?sort=created,这篇写得很好,总结了很多

关于gulp的使用,请见gulp的学习日志;

二,核心概念(entry,output,loader,plugins)

1,entry和context

context的作用是webpack会先从context配置的路径下检索entry文件;

如:

const config = {

  context: path.resolve('./src'),      //path.resolve([from...],to),将to参数解析为绝对路径,path是node模块

  entry: 'index.js'  

}

index.js文件放在src目录下;

webpack会创建一个由应用程序所有依赖构成的关系图(dependency graph),这个图的起点就是entry point,入口文件,从哪里开始,可以为单个入口,也可以为多个入口,语法可以是字符串,可以是对象,也可以是数组,对象的可扩展性较高

单个入口:

const config = {

  entry: "./index.js'  //字符串语法

};

module.exports = config;

等同于

const config = {

  entry: {

    main: "./index.js"  //对象语法

  }

};

module.exports = config;

也可以写多页面

const config = {
  entry: {
    pageOne: './src/pageOne/index.js',
    pageTwo: './src/pageTwo/index.js',
    pageThree: './src/pageThree/index.js'
 }
};
每一个key会是chunk的名称

2,output
入口起点可以多个,但是输出配置只有一个
两个必须的属性:
filename:输出文件名
path:输出目录,必须是绝对路径,否则会报错。
入口起点单个,最简单的例子:
const config = {
  output: {
    filename: 'bundle.js',
    path: '/home/proj/public/assets'
  }
};
如果多个入口起点
const config = {
 output: {
  filename: '[name].js',
  path: __dirname + '/dist'  //__dirname表示当前目录
 }
}
属性publicPath表示指定资源文件引用的目录,并不表示path前面可以省略publicpath里面定义的路径,比如
output: {
  publicPath: '/dist',
  path: path.resolve('./dist/js'),
  filename: 'bundle.js'
},
output.chunkFilename是做什么的?   (深恶痛绝,参加面试的时候问到了这个问题,一脸懵逼,听过但不懂干嘛的-。-)
此选项决定了非入口chunk文件的名称,可取值在下面的filename里
(关于output.filename:
1,对于单个入口起点,filename就是一个静态string,
filename: "bundle.js"
2,如果不是单个入口,为了区分不同的bundle,需要用下面中的一种替换方式来赋予每一个bundle唯一名称
filename: '[name].bundle.js'
使用内部chunk id
filename: '[id].bundle.js'
使用每次构建过程中,唯一的hash生成
filename: '[name].[hash].bundle.js'
使用基于每个chunk内容的hash
filename: '[chunkhash].bundle.js')

output.hotUpdateChunkFilename:自定义热更新chunk的文件名,可选值见上面filename,没必要修改这个值,默认就行
output还有一些其他属性,这里不一一介绍了,详见官网

3,loader,
对模块的源代码进行转换,可以在import或加载的时候(打包前)预处理文件,有点类似于task,在webpack2.0版本中,写法如下:
module: {
  rules: [
    {
      test: /\.txt$/,    //test用来识别出应该被对应的loader进行转换的文件,用正则写法
      use: 'raw-loader'   //use用来转换文件,并且使其能够被添加到dependency graph中,并最终添加到bundle中,注意webpack2里面loader必须写全,webpack1中loader可以只写‘-’前面的,但是2里面会报错
    }
  ]
}
我们也可以给use配置多个loader:
module: {
  rules: [
    {
      test: /\.css$/,
      use: [
        {loader: 'style-loader'},
        {
         loader: 'css-loader',
         options: {
           modules: true
         }
        }
      ]
    }
  ]
}
同样我们可以通过CLI使用loader,直接敲命令:
webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'
这会对.jade文件使用jade-loader,对.css文件使用style-loader和css-loader

每个rule分为三部分:条件,结果和嵌套规则:
1,条件:有两种输入值,resource:请求文件的绝对路径,相关属性是test,include,exclude,resource
             issuer:被请求资源的模块文件的绝对路径,相关属性是issuer
   这两种输入值解释一下,从app.js里面导入"./style.css",那么resource就是/path/to/style.css,而issure就是/path/to/app.js
  2,结果:有两种输入值,应用的loader:应用在resource上的loader数组,
              Parser选项:用于为模块创建解析器的选项对象。
      影响loader的属性:loader,options,use,query,loaders
  3,嵌套规则:属性rules,oneOf制定嵌套规则
 rule的其他属性,详见官方文档

4,plugin
插件的目的是解决loader无法实现的事
用法,向plugins属性传入new实例,下面我会列举一些常用的plugin

const HtmlWebpackPlugin = require('html-webpack-plugin');
const cleanWebpackPlugin = require('clean-webpack-plugin');
const webpack = require('webpack')
plugins: [
    new HtmlWebpackPlugin ({
    title: 'Hot Module Replacement'           //关于HtmlWebpackPlugin的参数配置,参考这个作者链接http://www.cnblogs.com/haogj/p/5160821.html
  }),
  new webpack.HotModuleReplacementPlugin(),        //模块热替换,
  new cleanWebpackPlugin(['dist']),             //清除dist文件夹
  new webpack.optimize.CommonsChunkPlugin({        //将公共的模块拆出来,合成的文件在最开始的时候加载一次就被浏览器缓存,速度上的提升。
    name: string,
    filename: string,
    minChunks: number|Infinity|function,
    chunks: string[],
    children: boolean
  })
]

5,其他配置:

devtool:开发环境下推荐用“cheap-module-eval-source-map”,生产环境下推荐用“source-map”,其他的选项见官方文档

webpack-dev-server: 这个不多说,就是本地起一个服务然后监听文件变化

webpack -p 等同于 webpack --optimize --define process.env.NODE_ENV="'production'",会执行如下步骤:
使用UglifyJsPlugin进行JS文件压缩,运行LoaderOptionsPlugin(主要是用来将webpack1迁移到webpack2上),设置NodeJS环境变量,触发某些package包,以不同的方式进行编译

devServer:配置项见官方文档,比较多,常用的几个:
devServer: {
  contentBase: path.resolve(__dirname, 'dist'),
  compress: true,        //一切服务都启用gzip压缩
  port: 9000,
  color: true,
  hot: true,
  hotOnly: true,
  open: true
}

6,Manifest
概念:当编译器开始执行、解析和映射应用程序时,它会保留所有模块的详细要点,这个数据集合就是Manifest
runtime:在模块交互时,连接模块所需的加载和解析逻辑,包括浏览器中已经加载的模块的连接,以及懒加载模块的执行逻辑。
当完成打包并发送给浏览器时,会在运行时通过Manifest来解析和加载模块,此时import或require已经转换成了__webpack_require__方法,此方法指向模块标识符,通过使用Manifest中的数据,runtime将能够查询模块标识符,检索出背后对应的模块。

7,target
webpack提供了多种构建目标target,表明了用于哪种环境下的javascript
node:编译为类Node.js环境可用
web:编译为类浏览器环境下可用(默认)
。。。。。。

8,懒加载
这里的懒加载指的是按需加载,只有用到模块的时候才会import进来,如下面的代码:
button.onclick = e => import(/* webpackChunkName: "print" */ './print').then(module => {
     var print = module.default;

     print();
   });
注意当调用 ES6 模块的 import() 方法(引入模块)时,必须指向模块的 .default 值,因为它才是 promise 被处理后返回的实际的 module 对象。
vue和react都有这种懒加载的方法,详细见官网
9,shimming
webpack在引入第三方库的时候,会有一些全局依赖,比如jquery的$符号,那么使用ProvidePlugin这个插件就可以用了,(实际项目中用到)
plugins: [
  new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery'
  })
]

10,环境变量
这里使用Node.js的process.env来引用变量
plugins: [
  new webpack.optimize.UglifyJsPlugin({
    compress: process.env.NODE_ENV === 'production'
  })
]
使用cross-env包来跨平台设置环境变量:
package.json
{
  "scripts": {
    "build": "cross-env NODE_ENV=production PLATFORM=web webpack"  
  }
}
 


webpack2学习日志的更多相关文章

  1. GRE学习日志

    发现开博客园真的很有督促作用,今天也顺便开个GRE学习日志吧 2015-02-09:单词 2015-02-10:单词 2015-02-11:单词 2015-03-02:阅读 2015-03-04:阅读 ...

  2. Cortex-M3学习日志(六) -- ADC实验

    上一次简单的总结了一下DAC方面的知识,好吧,这次再来总结一下ADC方面的东东.ADC即Analog-to-Digital Converter的缩写,指模/数转换器或者模拟/数字转换器.现实世界是由模 ...

  3. Cortex-M3学习日志(五) -- DAC实验

    终于逮了个忙里偷闲的机会,就再学一下LPC1768的外围功能吧,循序渐进是学习的基本规则,也许LPC1768的DAC与8位单片机16位单片机里面集成的DAC操作类似,但是既然这是懒猫的学习日志,就顺便 ...

  4. javascript学习日志:前言

    javascript学习日志系列的所有博客,主要理论依据是<javascript权威指南>(犀牛书第6版)以及<javascript高级程序设计第三版>(红色书),目前js行业 ...

  5. MobileForm控件的使用方式-用.NET(C#)开发APP的学习日志

    今天继续Smobiler开发APP的学习日志,这次是做一个title.toolbar.侧边栏三种效果 样式一 一.          Toolbar 1.       目标样式 我们要实现上图中的效果 ...

  6. 我的游戏学习日志3——三国志GBA

    我的游戏学习日志3——三国志GBA 三国志GBA由日本光荣公司1991~1995所推出<三国志>系列游戏,该作是光荣在GBA上推出的<三国志>系列作品的第一款.本游戏登场武将总 ...

  7. 【转】Cocos2d-x 3.1.1 学习日志6--30分钟了解C++11新特性

    [转]Cocos2d-x 3.1.1 学习日志6--30分钟了解C++11新特性 Cocos2d-x 3.1.1 学习日志6--30分钟了解C++11新特性

  8. composer的安装和使用 学习日志

    如果你做为一个phper,没有用过composer,那你真的不是一个合格的开发者.那么就来记录一下composer的学习日志 下面分享几个学习源头: composer中文网站:https://www. ...

  9. Python学习日志9月13日

    昨天的学习日志没有写,乱忙了一整天,政治电脑. 好奇心重,想要给电脑装上传说中LInux操作系统,各种小问题折腾到半夜,今天又折腾到晚上才真正的装上系统. 可是装上系统后又发现各种的不好用.虽然界面比 ...

随机推荐

  1. 再起航,我的学习笔记之JavaScript设计模式04

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 上回 ...

  2. golang 之验证码api

    知识一:如何返回一个json数据? 先定义一个结构体ResponseData,2个参数,并返回的是json数据,key就是json后定义的名称 type ResponseData struct { S ...

  3. Prerequisite check "CheckActiveFilesAndExecutables" failed.

    错误日志: [Aug , :: AM] Prerequisite check "CheckActiveFilesAndExecutables" failed. The detail ...

  4. [NOIP 2010]饮水入城 搜索+贪心

    考试的时候写了个dfs找出来了,最后处理的时候想到了贪心,但是正确性没有想通.然后想了想动规,也没想通.最后没办法,用状态的话用了个状压,弄了40分. 正解是bfs+贪心.Dfs也有过的. 下面题解引 ...

  5. UNIX 技巧: UNIX 高手的另外 10 个习惯

    让我们面对现实吧:坏习惯很难改变.但是您已经熟悉的习惯可能更难克服.有时,重新审视某些事情可能让您遇到“啊哈,我没想到它能做到这一点!”的时刻.在 Michael Stutz 的优秀文章“UNIX 高 ...

  6. shell /bin/bash^M: bad interpreter错误解决

      错误原因之一很有可能是你的脚本文件是DOS格式的, 即每一行的行尾以\r\n来标识, 其ASCII码分别是0x0D, 0x0A.可以有很多种办法看这个文件是DOS格式的还是UNIX格式的, 还是M ...

  7. Spring集成RabbitMQ-使用RabbitMQ更方便

    如果提到Spring,你脑海中对他的印象还停留在SSH三大框架之一,那或许你该好好重新认识这个家伙. 在IT技术日新月异的今天,他还能让你忘不了并与他朝夕相处,他,肯定有自己的绝活.如今他早已经不是孤 ...

  8. 利用 :before :after伪类实现鼠标悬浮动画效果

    1.最近在逛网站的时候,想找一下喜欢的鼠标悬浮效果,避免广告的嫌疑,直接放图了: 2.在实现的时候,如果在直接使用鼠标hover ,transform,进行过渡,不能达到想要的效果,因为同时只能触发一 ...

  9. php递归查找指定目录下及子文件名称是否包含中文空格及括号

    //php递归查找该目录下及子文件名称是否包含中文空格括号 function searchDir($path,&$data){ if(is_dir($path)){ $dp=dir($path ...

  10. .NET Core迁移技巧之web.config配置文件

    大家都知道.NET Core现在不再支持原来的web.config配置文件了,取而代之的是json或xml配置文件.官方推荐的项目配置方式是使用appsettings.json配置文件,这对现有一些重 ...