webpack集成了模块加载和打包等功能 ,这两年在前端领域越来越受欢迎。平时一般是用requirejs、seajs作为模块加载用,用grunt/gulp作为前端构建。webpack作为模块化加载兼容了amd/cmd模式,并且作为模块化的资源可以是js/css/image  coffeescript/sass/less  ES2015 modles TypeScript 等功能非常强大,作为前端构建工具还可以和grunt/gulp配合一起使用。 配置文件webpack.config.js也是非常清晰。

一. 安装webpack

npm install webpack -g 全局安装,这个时候可能会报错:npm warn optional dep failed...等错误, 可能是nodejs版本太低了 ,nodejs.org下载最新安装包即可 。

二. 命令行接口

1. 创建2个js文件

cats.js

var cats = ['dave', 'henry', 'martha'];
module.exports = cats;

app.js (主文件)

cats = require('./cats.js');
console.log(cats);

在命令行输出 :

webpack ./app.js app.bundle.js

将会生成合并压缩后的 app.bundle.js文件 。 可以直接当做nodejs模块执行: node  app.bundle.js 看效果。

三. 使用配置文件

在项目根目录下 npm init 创建package.json文件 。这时会提示输入package相关信息。

npm install webpack --save-dev  下载webpack模块并且将webpack加入package开发依赖(这样其他合作开发者就可以直接npm install啦)。

在项目根目录新建webpack.config.js 里面就是webpack的相关配置信息了 。

const webpack = require('webpack');  //加载webpack模块
module.exports = {
entry: './src/app.js', //主入口文件
output: {
path: './bin', //输出文件目录
filename: 'app.bundle.js' //输出文件名
},
plugins: [
new webpack.optimize.UglifyJsPlugin({ //使用uglifyjs插件
compress: {
warnings: false
},
output: {
comments: false
}
})
]
};

webpack自带了uglifyjs插件以及js loader,所以不需要自己添加额外的插件。

进入到项目根目录在命令行直接运行webpack就行了。会看到在bin目录多了个app.bundle.js文件。

目录结构:

|--src

|--bin

|--node-modules

|--webpack.config.js

对于文件夹的命名,webpack官网是这样说的:

In the wild, there are many project structures. Some projects use app instead of src. 
Some projects use dist or build instead of bin.
Projects with test usually use test, tests, spec, specs or colocate the test files in the source folder.

当需要加载其他特殊资源时需要下载相关的加载模块,比如:babel-loader 加载es2015 ( ECMAScript 6 简称ES6 , JavaScript语言的新标准。当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015 ) ,如果要兼容旧版浏览器还需要下载babel-polyfill, 这样就可以愉快的使用es6了。

四、输出编码格式

一般我们项目都是utf-8格式的,这时打包时默认输出utf-8编码格式的文件,如果需要输出其他格式的文档可以使用插件webpack-encoding-plugin ,插件支持的编码格式

比如需要输出GBK编码文件,只需要在webpack.config.js里面配置:

plugins:[new encodingPlugin('GBK')]

但是如果项目文件本身是gbk编码,而且有中文就比较麻烦了,如果还是按照上面的设置打包输出gbk编码,会发现中文乱码了。一直没找到好的方式解决这个问题,后来只能用nodejs先把需要打包的项目gbk文件copy一份写入一个临时目录比如:webpack-temp,写入的时候设置编码转换gbk->utf8 ,这样在临时目录就有一份和项目文件一样的文件,只是编码是utf8 (中文是好的),把这个转换的功能写入一个转换js模块。 在webpack打包的时候就直接require该js模块先执行转码,配置entry的时候路径指向临时目录webpack-temp, 调用webpack-encoding-plugin输出gbk编码文件。大功告成,中文没有出现乱码了。

转码关键代码:

 var fs = require('fs'),
iconv = require('iconv-lite');
var pathname = root + '/' + file,
from_code = 'GBK',
to_code = 'UTF8';
fs.writeFile(pathname , iconv.decode(fs.readFileSync(pathname), from_code), {
encoding: to_code,
mode:'0666'
}, function(err) {
if (err) {
throw err;
}
});

转码方法可以参考下这个:https://github.com/baixuexiyang/coding

五、常用webpack命令

webpack         // 最基本的启动webpack的方法
webpack -w // 提供watch方法;实时进行打包更新
webpack -p // 对打包后的文件进行压缩
webpack -d // 提供source map,方便调式代码
webpack --progress //显示进度
webpack --config xxx.js //调用不同的配置文件

对于比较长的命令可以写在package.json文件的scripts里面,然后通过scripts指定了运行脚本命令的npm命令行缩写,比如dev指定了运行npm run dev

"scripts": {
"dev": "webpack-dev-server --inline --hot --no-info"
}

六、使用sourcemap

devtool: "#source-map",   //使用#source-map打包会有点慢,使用#eval-source-map打包生成的文件放在一起体积会增加很多,不适合生产环境

devtool到底用哪个配置可以参考下这个:https://segmentfault.com/a/1190000004280859  ,不过写的还是比较模糊..

打开开发工具并且设置了Enable JavaScript source map选项才会下载map文件到本地, 打开source选项看到有webpack:// ,map文件就在里面。 设置了sourcemap需要把开发工具关了重新打开

在断点调试的时候发现要先在压缩的文件断点,然后点击 step over next function ... ,再点击exec... 就进入了map文件断点 。(有点奇怪)

sourcemap 报错问题可以参考这个:https://github.com/webpack/webpack/issues/91

七、使用CommonsChunkPlugin

当有多个文件require一个相同的文件的时候,在打包的时候我们可以把这个相同的文件提炼出来生成独立的common.js文件。

//a.js
require('./c.js');
...
//b.js
require('./c.js');
...
//c.js
var obj = ['132','test',13123];
module.exports = obj;

webpack相应配置:

plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'commons',
filename: "commons.js", //输出的文件名
minChunks: 2 //指一个文件至少被require几次才会被放到CommonChunk里,这一项一定要设置否则生成的common.js不会包含公共的文件
// (Modules must be shared between 2 entries) // chunks: ["pageA", "pageB"], //只提炼A、B里的公共文件
// (Only use these entries)
})
]

选项:

name:chunk的名称,如果这个chunk已经在entry中定义,该chunk会被直接提取;如果没有定义,则生成一个空的chunk来提取entry中其他所有chunk的公共代码。

filename:指定提取出的公共代码的文件名称。未定义时使用name作为文件名。如果代码要压缩,指定filename属性会有点问题发现代码没压缩,待查看

chunks:指定要提取公共模块的chunks,指定的chunk必须是公共chunk的子模块,如果没有指定则使用所有entry中定义的入口chunk。

minChunks:在一个模块被提取到公共chunk之前,必须被最少minChunks个chunk所包含。(一个模块至少要被minChunks个模块所引用,才能被提取到公共模块。)
该数字必须不小于2或者不大于chunks的个数。默认值等于chunks的个数。

如果指定了Infinity,则创建一个公共chunk,但是不包含任何模块,内部是一些webpack生成的runtime代码和chunk自身包含的模块(如果chunk存在的话)。

也可以给 minChunks 传入一个函数。这个函数会被 CommonsChunkPlugin 插件回调,并且调用函数时会传入 module 和 count 参数。

参考:

https://doc.webpack-china.org/plugins/commons-chunk-plugin

http://www.mamicode.com/info-detail-2042904.html

http://blog.csdn.net/liangklfang/article/details/54931523  //

通常用这个插件提取公共入口模块,以及项目的库文件(vue/vuex/vue-router等),webpack相关的运行公共代码(webpackJsonp定义,_webpack_require定义等)

//webpack入口配置
entry : {
vendor : ['vue','vue-router','vuex'], //项目中不变的库文件,可以单独打包到独立文件
main : ['./app/js/main.js'] //main.js里包含vue/vuex/vue-router等包引入,通过common插件提取到vendor
} ......
//经常使用vendor提取项目的库或插件文件, 用manifest提取入口的公共模块,包括webpack运行时的公共部分文件。 所以使用的时候注意manifest要在页面脚本最前面引入,其次再引入vendor
new webpack.optimize.CommonsChunkPlugin({
name:[ 'vendor','manifest'], //会到入口配置检查有没有对应的chunk, 如果有则直接提取入口的chunk到该commonchunk, 否则创建新的commonchunk
minChunks: Infinity,
}), //或分开写: new webpack.optimize.CommonsChunkPlugin({
name: 'vendor', //提取入口的vendor chunk 和 main chunk里引入的公共文件到vendor文件
minChunks: Infinity, //可以是一个function ,根据function判断chunk文件路径和文件目录信息,根据这些信息判断是否要创建chunk
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest', //创建新的chunk, 提取所有入口的公共部分(webpack相关运行代码和其他公共模块)
minChunks: Infinity,
}),

八、缓存和html-webpack-plugin

在处理缓存问题时,希望文件内容改变时更新缓存,可以用到chunkhash更改文件名,在输出文件时配置下文件名即可:

output:{
path:'./bin',
filename:'[name]-[chunkhash:8].js' //chunkhash默认会根据内容生成20位的hash, 可以通过配置参数控制位数。hash是每次webpack编译生成文件时都会变化,这里用chunkhash
},

这样当文件内容改变时文件名字就变化了,如果手动去改引用的路径太麻烦了。

可以用html-webpack-plugin来解决这个问题, 这个插件可以根据模版生成一个新的文件,新文件包含相应的入口文件引用。

所以html模版文件我们需要两份,一份是模板,一份是最终build的文件。模板里面也可以默认引入css和js,build的时候不会覆盖默认的引入文件。

安装html-webpack-plugin插件:

npm install html-webpack-plugin --save-dev

webpack.config.js配置:

var htmlWebpackPlugin = require('html-webpack-plugin');
......
entry:{
'test':root_path + '/test.js',
'aa': root_path + '/aa.js',
'dd': root_path + '/dd.js'
},
output:{
path:'./bin',
filename:'[name]-[chunkhash:8].js'
},
plugins:[
new htmlWebpackPlugin({
filename: '../index2.html', //相对于output.path,产出路径。
inject: true, //true/body为插到/body前面
template: 'index.html', //模版文件,相对于config文件路径
chunks:['aa','test'], //需要引入哪些块
chunksSortMode:'dependency' //引入块的排序,默认为auto, 改为dependency按照引入块数组顺序引入
}),
new htmlWebpackPlugin({
filename: '../aa2.html', //相对于output.path,产出路径。
inject: true,
template: 'aa.html',
chunks:['aa','test','dd']
}) //多个页面需要new多个htmlWebpackPlugin实现
]

更多参考:https://www.npmjs.com/package/html-webpack-plugin,http://www.cnblogs.com/haogj/p/5160821.html,https://github.com/lcxfs1991/html-res-webpack-plugin/blob/master/README_ZH.md

九、异步加载js模块

语法: require.ensure(dependencies: String[], callback: function([require]), [chunkName: String])
dependencies: 依赖的模块数组
callback: 回调函数,该函数调用时会传一个require参数
chunkName: 模块名,用于构建时生成文件时命名使用
注意:requi.ensure的模块只会被下载下来,不会被执行,只有在回调函数使用require(模块名)后,这个模块才会被执行。

require.ensure会创建一个chunk,且可以指定该chunk的名称,如果这个chunk名已经存在了,则将本次依赖的模块合并到已经存在的chunk中,最后这个chunk在webpack构建的时候会单独生成一个文件

比如:

require.ensure([], function(require){
var ensure = require('./test/1.js');
console.log(ensure);
},'ensure2')

在webpack.config.js文件需要配置output

output: {
path: __dirname+'/bin',
filename: '[name].js',
chunkFilename:'[name].js', //require.ensure异步请求设置生成的文件名,默认是数字,可以在require.ensure第三个参数配置这个名字
publicPath:__dirname+'/bin/' //require.ensure异步请求的模块,在打包时提取出来生成文件存放在这个目录
},

参考:http://blog.csdn.net/zhbhun/article/details/46826129

npm设置镜像

1. 命令行:npm config set registry http://registry.npm.taobao.org

2. 打开配置文件:C:\Users\Administrator\.npmrc

修改其中内容为:registry = http://registry.npm.taobao.org

参考文档:

https://github.com/petehunt/webpack-howto

http://webpack.github.io/docs/usage.html

http://www.cnblogs.com/vajoy/p/4650467.html

https://www.npmjs.com/package/webpack-encoding-plugin

http://www.fantxi.com/blog/archives/webpack/

https://github.com/kairyou/demo/blob/master/webpack/webpack.cfg.js

webpack学习笔记一(入门)的更多相关文章

  1. python学习笔记--Django入门四 管理站点--二

    接上一节  python学习笔记--Django入门四 管理站点 设置字段可选 编辑Book模块在email字段上加上blank=True,指定email字段为可选,代码如下: class Autho ...

  2. WebSocket学习笔记——无痛入门

    WebSocket学习笔记——无痛入门 标签: websocket 2014-04-09 22:05 4987人阅读 评论(1) 收藏 举报  分类: 物联网学习笔记(37)  版权声明:本文为博主原 ...

  3. Java学习笔记之---入门

    Java学习笔记之---入门 一. 为什么要在众多的编程语言中选择Java? java是一种纯面向对象的编程语言 java学习起来比较简单,适合初学者使用 java可以跨平台,即在Windows操作系 ...

  4. DBFlow框架的学习笔记之入门

    什么是DBFlow? dbflow是一款android高性的ORM数据库.可以使用在进行项目中有关数据库的操作.github下载源码 1.环境配置 先导入 apt plugin库到你的classpat ...

  5. MongoDB学习笔记:快速入门

    MongoDB学习笔记:快速入门   一.MongoDB 简介 MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统.在高负载的情况下,添加更多的节点,可以保证服务器性能.M ...

  6. 【原】webpack学习笔记

    之前在react的项目中有用过webpack,不过没有认真的去研究,这段时间又重新好好的学习一下webpack,发觉 webpack是一个很强大的东西.而且很好用,方便,接下来主要是做一下学习的笔记 ...

  7. 学习笔记_J2EE_SpringMVC_01_入门

    1.    概述 笔者作为一个不太正经的不专业佛教信仰者,习惯了解事物的因果关系,所以概述就有点BBB...了.如果不喜欢这些的,请自行跳过概述章节,直接进入第二章的操作实践:2 入门示例. 1.1. ...

  8. dubbo入门学习笔记之入门demo(基于普通maven项目)

    注:本笔记接dubbo入门学习笔记之环境准备继续记录; (四)开发服务提供者和消费者并让他们在启动时分别向注册中心注册和订阅服务 需求:订单服务中初始化订单功能需要调用用户服务的获取用户信息的接口(订 ...

  9. SpringBoot学习笔记<一>入门与基本配置

    毕业实习项目技术学习笔记 参考文献 学习视频 2小时学会Spring Boot:https://www.imooc.com/learn/767 学习资料 SpringBoot入门:https://bl ...

  10. [学习笔记]SiftGPU入门

    当有读者看到我这篇SiftGPU入门的学习笔记时,相信你已经读过了高博那篇<SLAM拾萃:SiftGPU>,那篇文章写于16年,已经过去两年的时间.在我尝试配置SiftGPU的环境时,遇到 ...

随机推荐

  1. 【HDOJ】1823 Luck and Love

    二维线段树.wa了几次,不存在输出-1,而不再是一位小数. #include <cstdio> #include <cstring> #define MAXN 105 #def ...

  2. Python根据上下限生成不重复随机数1

    Python 2.7.5代码: #coding=utf-8 import random #定义计数器,默认为0 num=0 #定义随机结果集,默认为空列表 choose_resault=[] #最多可 ...

  3. 51Testing丛书新作《软件测试工程师面试秘籍》

    51Testing又有好消息告诉小伙伴了!51Testing软件测试网作品系列重磅推出全新丛书<软件测试工程师面试秘籍> 此次我们邀请到知名互联网企业测试专家李江(G.li),整理并撰写软 ...

  4. 【转】使用unity3d需要注意到细节

    原 文:http://cache.baiducontent.com /c?m=9d78d513d9841df41ea6837e7c01a6660e20f6743da7c76508c3e34f84152 ...

  5. Hibernate(一)JDBC简介

    在了解Hibernate之前,我们先回顾一下传统JDBC访问数据库的相关内容.重点在于分析JDBC访问存在哪些 缺陷,这些缺陷在Hibernate中是如何思考和解决的? JDBC主要对象 DriveM ...

  6. scrollView的用法

    - (void)viewDidLoad {     [super viewDidLoad];           scrollView = [[UIScrollView alloc] initWith ...

  7. Hibernate的Session会话中get()和load()方法的区别

    1.get和load都可以从数据库中获取数据 .get拿到的是真的对象,load拿到的是代理对象 2.get和load从数据库中获取数据,如果获取不到,get返回null,load会出现ObjectN ...

  8. tomacat 配置ssl协议

    1.首先用jdk自带的工具keytool生成一个"服务器证书" a.命令行进入$JAVA_HOME/bin目录($JAVA_HOME为jdk的安装目录) b.输入:keytool ...

  9. request.setAttribute()用法

    小问题: JSP1代码 String [] test=new String[2]; test[0]="1"; test[1]="2"; request.setA ...

  10. maven 私服 配置 转

    3 . Nexus预置的仓库 点击左侧 Repositories 链接,查看 Nexus 内置的仓库: Nexus 的仓库分为这么几类: hosted 宿主仓库:主要用于部署无法从公共仓库获取的构件( ...