webpack简介
webpack是一个基于模块化的打包(构建)工具, 它把一切都视作模块
它通过一个开发时态的入口作为起点, 分析出所有的依赖关系, 然后经过一系列的过程(压缩, 合并), 最终生成线上环境的文件
webpack的特点:
- 为前端工程化而生: webpack致力于解决前端工程化, 特别是浏览器工程化中遇到的问题, 让开发者集中注意力编写业务代码, 把工程化过程中问题交给webpack
- 简单易用: 支持零配置, 可以不用写任何一行额外的代码就可以使用webpack
- 强大的生态: webpack是非常灵活, 可以扩展的, webpack本身的功能并不多, 但他提供一些可以扩展其功能的机制, 使得一些第三方库可以融入到webpack中
- 基于nodejs: 由于webpack在构建的过程中需要读取文件, 因此它是运行在node环境中的
- 基于模块化: webpack在构建过程中要分析彼此的依赖关系, 方式是通过模块化导入语句分析的, 他支持各种模块化标准, 包括但不限于
commonjs
,es6 module
webpack的安装
webpack通过npm安装, 它提供了两个包:
- webpack: 核心包, 包含了webpack在构建过程中要用到的所有api
- webpack-cli: 提供一个简单的cli命令, 它调用了webpack核心包的api来完成构建
安装方式:
- 全局安装: 可以全局使用webpack命令, 但是无法为不同项目对应不同的webpack版本
- 本地安装: 推荐, 每个项目都使用自己的webpack版本进行构建
npm install webpack webpack-cli -dev // webpack和webpack-cli的安装
webpack的使用
使用的话你可以只用一条命令
webpack
默认情况下, webpack会以./src/index.js
作为入口文件并分析依赖关系, 打包到./dist/main.js
文件中
通过
--mode
选项可以控制webpack打包结果的运行环境
我们可以在文件夹根目录下新建一个src文件夹, 并创建index.js文件, 结构如下
index.js文件如下
// 你也可以随便写写, 想写啥就写啥, 我们最终要看的也就是webpack的编译结果
console.log('hello, Webpack');
const name = 'loki';
const foo = () => {
return 'helloWorld';
}
我们在工程根目录下执行如下命令
npx webpack
我们会发现根目录下生成了一个dist文件夹, 里面生成了一个main.js文件, 我们打开发现如下
// dist/main.js
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t){console.log("hello, Webpack")}]);
这就是通过webpack处理过后的线上环境的文件了
我们来看看之前的jQuery的问题, 来看看webpack的魔力之处, 我们先安装jQuery
npm install jquery -S
我们知道, jQuery是用commonjs的规范导出的, 所以我们之前在ES6 module中会报错, 但是用了webpack以后就完全不一样了
// src/index.js
import $ from 'jquery';
console.log($);
然后我们打包一下
npx webpack
然后将dist中的main.js引入index.html中
我们发现jQuery打印出来了, 这就是webpack为我们做的事情, 在webpack打包之前, 我们可以尽情的书写我们想写的代码, 什么commonjs规范, 什么es6规范, 想用啥就用啥, 甚至后面的less, sass, 还有图片压缩, 文件压缩我们在开发环境里完全不用管, webpack会帮助我们处理好, 这是不是太爽了
快捷命令
如果你用过vue或者react的话, 你肯定知道
npm run build
或者npm build
这两个命令, 其实这两个命令就是在操作webpck, 内部调用的也是webpack
命令, 我们现在也可以做到, 在package.json
中修改一下代码
// package.json
...
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack", // 在script字段中加上build这行代码, 让他去找webpack命令执行
},
...
这样保存以后我们再去Terminal中输入npm run build
就也可以生成dist文件夹了
所以如果你搞不懂webpack, 你甚至都很难知道在vue, react这类工程化项目中的一些细节到底是怎么处理的
关于Terminal中出现的警告
如果你仔细观察, 你会发现在我们使用
npx webpack
或者npm run build
的时候, 打包成功以后, 其实他是给我们提供了一些信息的, 其他的信息我们先不说, 就先看看这个黄色的警告
这个警告是在告诉我们, 我们没有给这次打包设置mode
选项, webpack将默认以production进行打包, 其实mode
选项也是让我们设置打包后的代码到底是在生产环境用还是开发环境用, 开发环境的话他给你打包的代码让你尽可能方便调试, 生产环境的话他会压缩成一行就像上面的例子一样, 然后webpack的意思是让我们尽量指定一下模式, 别老让他走默认模式
npx webpack --mode=development // 设置为开发环境, 如果设置为生产环境的话就是--mode=production
这样每次在Terminal中敲这个命令也太烦了, 我们可以到package.json
中修改一下
// package.json
...
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --mode=production", // build的话就将mode设置为production
"dev": "webpack --mode=development", // 设置development
},
...
于是自此以后, 我们运行npm run build
就是直接打包成dist
压缩文件, 而npm run dev
就是打包成开发调试文件啦