一、 什么是webpack
1、官方解释
本质上讲, webpack 是一个现代 JavaScript 应用程序的静态模块打包器。(模块和打包)
2、前端模块化
- 前端模块化的一些方案: AMD、 CMD、 CommonJS、 ES6
- 浏览器不能识别它们, 但是webpack 可以做它们的底层支撑,方可进行模块化开发
 
 - ES6 之前, 要想进行模块化开发, 就必须借助于其他的工具, 让我们进行模块化开发
 - 并且通过模块化开发完成了项目后, 还需要处理模块化间的各种依赖, 并且将其进行整合打包
 - 此时出现 webpack, 其中一个核心就是让我们可能进行模块化开发, 并且会帮助我们处理模块间的依赖关系。
 - 而不仅仅是JavaScript文件,我们的css、图片、json 文件等等在webpack 中都可以被当作模块来使用
 
3、打包如何理解
- webpack 可以帮助我们进行模块化, 并且处理模块间的各种复杂关系后, 打包的概念就很好理解了
 - 就是将 webpack 中的各种资源模块进行打包合并成一个或多个包(bundle)
 - 并且在打包的过程中, 还可以对资源进行处理, 比如压缩图片, 将scss 转成 css, 将ES6 语法转成ES5 语法, 将TypeScript 转成 JavaScript 等等操作
 - 打包工具还有 grunt/gulp
 - webpack 和 grunt/gulp 的对比
- grunt/gulp 的核心是Task
- 可以配置一系列的task, 并且定义 task 要处理的事务(例如 ES6、ts转化、图片压缩、scss转成css)
 - 之后让grunt/gulp 来依次执行这些task, 而且让整个流程自动化
 
 - 看一个gulp 的 task
- 下面的task 就是将src 下面的所有js 文件转成 ES5 的语法
 - 并且最终输出到dist 文件夹中
 
 - 什么时候使用grunt/gulp?
- 工程模块依赖非常简单, 甚至没有用到模块化的概念
 - 只需要进行简单的合并、压缩, 就使用grunt/gulp 即可
 - 如果整个项目使用了模块化管理, 而且相互依赖非常强, 我们就可以使用webpack
 
 - grunt/gulp 和 webpack 有什么不同
- grunt/gulp 更加强调的是前端流程的自动化, 模块化不是它的核心
 - webpack 更加强调模块化开发管理, 而文件压缩合并、预处理等功能, 是她附带的功能
 
 
 - grunt/gulp 的核心是Task
 
二、webpack 安装
webpack 为了正常运行必须依赖node 环境, 而node 环境为了可以正常执行,必须使用 npm 工具管理 node中各种依赖包
- 因此 安装webpack 首先要安装Node.js, Node.js 自带了软件包管理工具 npm
 - 全局安装 webpack (npm install webpack@3.6.0 -g)
 局部安装 webpack (npm install webpack@3.6.0 —save-dev) —save-dev 是开发时依赖,项目打包后不再需要继续使用
三、webpack 的配置
1、文件和文件夹解析
dist文件夹: 用于存放打包之后的文件
- src 文件夹: 用于存放我们写的源文件
- main.js 项目的入口文件
 - mathUtils.js 定义了一些数学工具函数, 可以在其他地方引用, 并且使用
 - index.html 浏览器打开展示的首页html(在这里引用的是 src 内最终打包的文件 即 dist 文件夹的内容)
 - package.json 通过npm init 生成的, npm 包管理文件
 
 
(CommonJS模块化规范, CommonJS 是模块化的标准, nodejs 就是 CommonJS 模块化的实现)
2、命令
webpack ./src/main.js ./dist/bundle.js (将 main.js 文件打包成 bundle.js 文件)
说明: 也可以使用 ES6 的模块化规范
// 使用commonjs 的模块化规范const { add, mul } = require('./mathUtils.js')console.log(add(20, 30));console.log(mul(20, 30));// 使用 ES6 的模块化规范import { name, age, height } from './info'console.log(name);console.log(age);console.log(height);
3、创建 webpack.config.js 文件简化打包命令
(将打包命令映射为打包入口和出口)
const path = require('path')module.exports = {entry: './src/main.js',output: {path: path.resolve(__dirname, 'dist'),filename: 'bundle.js'}}
- entry: 为打包的入口
 - output: 为打包的出口
- output 中的path 我们需要动态获取
 - 因为我们可以使用Node.js 语法导入一个模块这个模块path [ const path = require(”path”)] 引号内的文件是需要在node 包里找到
 - 通过npm init 命令(初始化)使用node.js
 - 之后生成 package.json 文件(该文件描述当前项目的信息)
- license: “ISC” 为开源项目
 
 
 
说明: 如果想使用node, 必须依赖于 package.json 文件
{"name": "meetwebpack","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \'Error: no test specified\' && exit 1"},"author": "","license": "ISC"}
运行 npm install webpack@3.6.0 —save-dev 之后,增加了如下依赖
{"name": "meetwebpack","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \'Error: no test specified\' && exit 1","build": "webpack"},"author": "","license": "ISC","devDependencies": {"webpack": "^3.6.0"}}
4、将webpack 命令映射 npm run
除了将 webpack 映射入口、出口之外, 还可以将webpack 命令映射为 npm run 一些操作(需要在 package.json 内”script” 脚本标签中修改)
四、loader 的使用
1、什么是loader
- loader 是webpack 中一个非常核心的概念
 
webpack 用来做什么?
- 主要用webpack 处理js代码, 并且 webpack 会自动处理 js 之前相关的依赖
 - 但, 在开发中不仅要处理js代码, 还需要加载css、图片,一些高级的如将 ES6 转成ES5代码, 将 scss、less 转成 css, 将jsx、.vue 文件转成js 文件等
 - 对于webpack 本身的能力来说,这些转化是不支持的
 此时可以交给 webpack 扩展 对应的 loader 来处理
2、loader 使用示例
示例1: css 文件处理
通过 npm 安装需要使用的loader
- npm install —save-dev css-loader
 - npm install —save-dev style-loader
 
在 webpack.config.js 中的modules 关键字下进行配置
安装对应的loader
- npm install —save-dev less-loader less(安装less 是 对less 文件进行编译)
 
- 修改对应的配置文件, webpack.config.js 文件中的rules 数组中新增一个对象处理.less 文件
 
{test: /\.(png|jpg|gif|jpeg)$/,use: [{loader: 'url-loader',options: {// 当加载的图片,小于limit 时, 会将图片编译成 base64 字符串形式// 当加载的图片,大于limit 时, 需要使用file-loader 模块进行加载limit: 8196}}]}
打包后
会发现dist文件夹下多了一个图片文件
说明
- webpack 会自动帮我们生成一个非常长的名字
- 这是一个 32位 hash值, 目的是防止名字重复
 - 但是实际开发中, 可能对打包的图片名字有一定的要求
 
 - 可以在options 中添加如下选项
- img: 文件要打包到的文件夹
 - name: 获取图片原来的名字,放在该位置
 - hash8: 为了防止图片名字冲突, 依然使用hash, 但只保留8位
 - ext:  使用图片原来的扩展名
另外, 配置图片修改图片使用的路径可以在 output 下的 publicPath 中配置{test: /\.(png|jpg|gif|jpeg)$/,use: [{loader: 'url-loader',options: {// 当加载的图片,小于limit 时, 会将图片编译成 base64 字符串形式// 当加载的图片,大于limit 时, 需要使用file-loader 模块进行加载limit: 8196,name: 'img/[name].[hash:8].[ext]'}}]}
示例4: ES6转ES5的babel
npm install —save-dev babel-loader@7 babel-preset-es2015
 
 
配置webpack.config.js 文件
{test: /\.m?js$/,exclude: /(node_modules|bower_components)/,use: {loader: 'babel-loader',option: {presets: ['es2015']}}}
重新打包后,会发现 bundle.js 文件内容变成了es5 的语法
五、plugin 的使用
HtmlWebpackPlugin | webpack 中文文档
1、认识plugin
- plugin 是什么?
- plugin 是插件的意思, 通常是用于对某个现有的架构进行扩展
 - webpack 中的插件, 就是对webpack现有功能的各种扩展, 比如打包优化、文件压缩等
 
 - loader 和 plugin区别
- loader 主要用于转化某些类型的模块, 他是一个转化器
 - plugin 是插件, 他是对webpack本身的扩展, 是一个扩展器
 
 - plugin 的使用过程
- 通过npm 安装需要使用plugins (某些webpack已经内置的插件不需要安装)
 - 在 webpack.config.js 中的plugins中配置插件
 
 
2、webpack 添加版权信息 Plugin 的使用
使用插件, 为打包的文件添加版权声明, 该插件名字叫 BannerPlugin, 属于 webpack 自带的插件
const path = require('path')const webpack = require('webpack')module.exports = {...plugins: [new webpack.BannerPlugin('最终版权归coderwhy所有')]}
3、打包html的plugin

4、js压缩的plugin


