简单来讲,Webpack 就是一个针对 JavaScript 代码的模块打包工具。css
gulp:html
webpackjquery
gulp是工具链、构建工具,能够配合各类插件作js压缩,css压缩,less编译 替代手工实现自动化工做
若是咱们平常使用的时候,不须要使用模块化这个概念,开发的JS随便在一个JS里就OK的状况,或者没有什么联动性的做用,可使用sublime+gulp+browersync+babel
webpack利用模块化的概念,基本上通通都用js来写,Webpack的处理速度更快更直接,能打包更多不一样类型的文件。webpack
首先建立一个webpackdemo的文件夹,而后命令行进入到该文件夹下,执行npm init
,而后一路回车,输入yes后就能够看到文件夹下的package.json
文件,这也是咱们全部包都须要的文件依赖。es6
//全局安装 npm install -g webpack --registry=http://registry.npm.taobao.org //安装到你的项目目录 npm install --save-dev webpack --registry=http://registry.npm.taobao.org
先来建立三个文件,一个是html,一个是咱们即将使用的主入口文件index.js,一个是咱们将要引用的文件person.jsweb
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script src="./build/bundle.js"></script> </body> </html> //index.js import Person from './second'; let app = document.createElement('div'); app.className='MyDiv'; app.innerHTML = '<h1>Hello World,I am the index content</h1><h2>Hi,I am the vice content<h2>'; let luren = new Person('张三',18); document.body.appendChild(app); console.log(luren.say()); //second.js class Person{ constructor(name, age){ this.name = name; this.age = age; } say(){ return `我是${this.name},我今年${this.age}岁了。`; } } export default Person;
光有了package.json
还不够,为了更方便,不用本身每次都去输入各类命令,还要有webpack.config.js
文件npm
// entry 入口文件 让webpack用哪一个文件做为项目的入口 // output 出口 让webpack把处理完成的文件放在哪里 // module 模块 要用什么不一样的模块来处理各类类型的文件 var path = require('path'); //定义了一些文件夹的路径 var ROOT_PATH = path.resolve(__dirname); var APP_PATH = path.resolve(ROOT_PATH, 'src'); var BUILD_PATH = path.resolve(ROOT_PATH, 'build'); module.exports = { //项目的文件夹 能够直接用文件夹名称 默认会找index.js 也能够肯定是哪一个文件名字 entry: APP_PATH, //输出的文件名 合并之后的js会命名为bundle.js output: { path: BUILD_PATH, filename: 'bundle.js' }, //webpack使用loader的方式来处理各类各样的资源/2.0叫rules,区别不是很大,任何文件运行想要解析都须要通过loader module: { rules: [ { test: /\.jsx?$/,//首先先去匹配咱们的include文件夹下的包含.js或.jsx后缀名的文件 include: APP_PATH,//目标文件夹 use: ['babel-loader']//使用babel-loader处理这些文件 } ] }, };
以上就是一个最简单的webpack.config.js配置文件,其中loaders部分里只写了一个babel,就是为了咱们能快点先看到东西,因此咱们要先装上babelnpm install babel-core babel-loader babel-preset-latest --save-dev --registry=http://registry.npm.taobao.org
。
这里babel-core
顾名思义是babel的核心编译器. babel-preset-latest
是一个配置文件, 意思是转换ES2015/ES2016/ES2017到ES5, 不仅ES6. babel还有其余配置文件. 若是只想用ES6, 能够安装babel-preset-es2015:
执行webpack
,咱们能够看到build里多了一个文件bundle.js,可是只有文件,这样的话没有服务器也是很麻烦,每次改动都须要手动执行webpack
。而webpack自带的一个强大的功能就是自带开发服务器。json
npm install webpack-dev-server --save-dev --registry=http://registry.npm.taobao.org
gulp
安装完成后,如何使用它呢,确定是要在配置文件里写上dev-server的配置的数组
// devserver配置选项 功能描述 // port 设置默认监听端口,若是省略,默认为”8080“ // inline 设置为true,当源文件改变时会自动刷新页面 // colors 设置为true,使终端输出的文件为彩色的 // historyApiFallback 在开发单页应用时很是有用,它依赖于HTML5 history API,若是设置为true,全部的跳转将指向index.html module.exports = { .... devServer: { host:'0.0.0.0',//有了这个参数,写上0.0.0.0,咱们就能够用ip地址访问了,没有的话若是别人访问会被禁止掉的 historyApiFallback: true, hot: true, inline: true, //progress: true, 已经废弃,别写上去 }, ... }
如今配置文件也有了,咱们就能够走一把,运行webpack-dev-server --hot --inline
。而后把咱们的html文件中的script标签中的src给改掉<script src="http://localhost:8080/bundle.js"></script>
,任意改动文件,就能够看到效果了。这个时候,有的同窗说本身记不住这个命令怎么办。那么就把这命令写进package.json
里面吧。
// npm的start是一个特殊的脚本名称,它的特殊性表如今,在命令行中使用npm start就能够执行相关命令, // 若是对应的此脚本名称不是start,想要在命令行中运行时,须要这样用npm run {script name}如npm run build ... "scripts": { "start": "webpack-dev-server --hot --inline" }, ...
下面是webpack-dev-server里的一些具体参数,能够看看。
npm install css-loader style-loader --save-dev --registry=http://registry.npm.taobao.org
而后修改下webpack.config.js的配置文件
//css-loader会遍历css文件,找到全部的url(...)而且处理 //style-loader会把全部的样式插入到你页面的一个style tag中 { test: /\.css$/, use: ['style-loader', 'css-loader'], include: APP_PATH }
可是如今不少小伙伴又都喜欢使用less
或者是sass
,以less
为例子,运行npm install less-loader less --save-dev --registry=http://registry.npm.taobao.org
,而后再rule中修改正则和use也就是1.x版本中的loaders
{ test: /\.css|.less$/, use: ['style-loader', 'css-loader','less-loader'],//一旦use参数里的loader是一个数组,记住,执行顺序是从右向左,若是写错了那就会有问题了。 include: APP_PATH }
css里面也能够模块化的引用其余css,@import 'xxx.less';
,记住,必定要打分号,不像是js是弱类型能够不带,这个不带回报错的。
处理完了css/less,如今我须要引用图片了,怎么办,假如我在样式里写了网络路径的图片,是没有问题的,可是假如我随便写了一个本地路径的图片
.MyDiv{ background: url('./img/smallPic.png'); }
运行会发现报错了,错误信息是
仍是很清楚的,它说它须要单独处理该文件的话须要咱们弄一个loader也就是rules来处理他们
执行npm install url-loader file-loader --save-dev --registry=http://registry.npm.taobao.org
,而后添加处理图片的loader
{ /* css-loader引用的图片和字体一样会匹配到这里的test条件 */ test: /\.(png|jpg|jpeg|gif|eot|ttf|woff|woff2|svg|svgz)(\?.+)?$/, /* 使用url-loader, 它接受一个limit参数, 单位为字节(byte) 当文件体积小于limit时, url-loader把文件转为Data URI的格式内联到引用的地方 当文件大于limit时, url-loader会调用file-loader, 把文件储存到输出目录, 并把引用的文件路径改写成输出后的路径 */ use: [ { loader: 'url-loader', options: { limit: 10000 } } ] },
而后没讲的是css的autoprefix
功能,直接用你的编辑器快速补全吧,很方便的
{ "babel": { "presets": [ [ "latest", { "es2015": { "loose": true, "modules": false } } ] ] }
使用后运行webpack能够发现bundle文件的行数会变小不少
plugins: [ //这个使用uglifyJs压缩你的js代码,仅限生产环境,不然sourcemap找不到 new webpack.optimize.UglifyJsPlugin({minimize: true}) ]
能够看到这里使用了一个新的名词,plugins,就是一旦使用插件类的,都须要在plugins来写,不少写插件的话须要声明一个webpack。
在配置文件的最上面来写var webpack = require('webpack');
;
`npm install jquery --save-dev --registry=http://registry.npm.taobao.org` plugins: [ ... new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery", "window.jQuery": "jquery" }) ... ]
这个时候会发现咱们的bundle.js文件超级大,由于jquery也被打进去了,因此咱们须要作拆分工做,把咱们引用的三方库给分离出来。
entry: { app: APP_PATH, //添加要打包在vendors里面的库 vendors: ['jquery'] }, //输出的文件名 合并之后的js会命名为bundle.js output: { path: BUILD_PATH, filename: '[name].js' }, plugins: [ ... new webpack.optimize.CommonsChunkPlugin({ names: ['vendors'] }) ... ]
再手动把html引用的script给换掉就能够了。
好多模式,该用哪一个,开发用cheap-module-eval-source-map
这个绝大多数状况下都会是最好的选择,这也是下版本 webpack 的默认选项。不方便看的话就直接source-map
,就是文件大点
创建生产配置文件webpack.production.config.js
,而后去掉dev的配置,写进package.json
里"build": "webpack --progress --profile --colors --config webpack.production.config.js"
,运行npm run build
便可