什么是webpack?
官方解释:从本质上讲,webpack是一个现代的JavaScript应用的静态 模块打包 工具。
重点:模块、打包
我们在开发项目时,可能会有很多的不同类型的文件,如果直接把这些文件发送给服务器,让服务器部署,很可能在浏览器中是不能直接运行的,比如.sass文件是浏览器不支持的,需要经过一些工具进行打包转化,生成浏览器可以识别执行的代码。目前有很多打包工具可用,比如grunt、gulp、webpack、rollup,其实vue的源码就是rollup进行构建的。
前端模块化
前端模块化
- 目前使用前端模块化的一些方案:AMD、CMD、CommonJS、ES6
- 在ES6之前,我们想要进行模块化开发,就必须借助于其他的工具,让我们可以进行模块化开发,并且在通过模块化开发完成项目之后,还需要处理模块间的各种依赖,并且将其进行整合打包。
- webpack其中一个核心就是让我们可能进行模块化开发,并且会帮助我们处理模块之间的依赖关系,不仅仅是js文件,css、图片、json文件等等在webpack中都可以被当做模块来使用。
打包如何理解?
- 打包就是将webpack中的各种资源模块进行打包合并成一个或多个包(Bundle)
- 在打包的过程中,还可以对资源进行处理,比如压缩图片,将scss转成css,将ES6语法转成ES5语法,将TypeScript转成JavaScript等等操作
webpack和grunt/gulp的对比
目前前端用得最多的是webpack,但grunt/gulp也可以完成一些打包的操作,它们之间还是有很多区别的。
- grunt/gulp的核心是Task(其实就是定义任务流)
我们可以配置一系列的task,并且定义task要处理的事务(例如ES6、ts转化、图片压缩、scss转成css),之后让grunt/gulp来依次执行这些task,而且让整个流程自动化,所以grunt/gulp也被称为前端自动化任务管理工具。
举例:gulp的task
const gulp = require("gulp");
const babel = require("gulp-babel");
gulp.task("js", ()=>
gulp.src("src/*.js")
.pipe(babel({
presets:["es2015"]
}))
.pipe(gulp.dest("dist"))
);
上边代码的task就是将src下面的所有js文件转成ES5的语法,并且最终输出到dist文件夹中。
什么时候用grunt/gulp?
- 如果你的工程模块依赖非常简单,甚至是没有用到模块化的概念,只需要进行简单的合并、压缩,使用grunt/gulp即可
- 如果整个项目使用了模块化管理,而且相互依赖非常强,就可以使用更加强大的webpack了
总结:
grunt/gulp更加强调的是
前端流程的自动化
,模块化不是它的核心
webpack更加强调的是模块化开发管理
,而文件压缩合并、预处理等功能,是它附带的功能
webpack安装
webpack为了正常运行,必须依赖node环境。安装webpack首先需要安装Node.js,Node.js自带了软件包管理工具npm
查看自己的node版本:
node -v
全局安装webpack
npm install webpack -g
局部安装webpack(后续才需要)
--save-dev
是开发时依赖,项目打包后不需要继续使用的。
npm install webpack@3.6.0 -g
为什么全局安装后,还需要局部安装呢?
- 在终端直接执行webpack命令,使用的全局安装的webpack
- 当在package.json中定义了scripts时,其中包含了webpack命令,那么使用的是局部webpack
一般在开发的项目所在的根目录下会包含两个文件夹:
- src:源码,自己写的源码一般会放在src文件夹中
- dist:全称是distribution(发布),存放打包好的文件
src下一般会有一个main.js(或者index.js)文件,作为整个程序的入口文件
例子:模块化编程
commonJS规范:
mathUtil.js
function add(num1, num2) {
return num1+num2;
}
function multiply(num1, num2) {
return num1*num2;
}
module.exports = {
add,
multiply
};
main.js
const {add, multiply} = require('./mathUtil');
console.log(add(1, 2));
console.log(multiply(1, 2));
此时,在index.html中不能直接通过script引用main.js,因为main.js中包含了commonJS规范的代码,不能被浏览器识别。这时候可以使用webpack对js文件进行打包,只需要打包出一个浏览器能够识别的文件然后让index.html进行引用就可以了。
webpack ./src/main.js ./dist/bundle.js
这句话的意思就是用webpack这个工具,将src下的main.js打包到dist下的bundle.js,webpack会自动处理模块之间的依赖。
生成的bundle.js
核心代码: 通过这个函数处理模块间的依赖
function __webpack_require__(moduleId) {
......
}
打包完的东西在最下面,会被__webpack_require__
函数解析
/***/ (function(module, exports) {
function add(num1, num2) {
return num1+num2;
}
function multiply(num1, num2) {
return num1*num2;
}
module.exports = {
add,
multiply
};
/***/ })
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="./dist/bundle.js"></script>
</body>
</html>
结果:
使用ES6:
info.js
export const name = "wu";
export const age = 23;
export const height = 160;
main.js
// commonjs
const {add, multiply} = require('./mathUtil');
console.log(add(1, 2));
console.log(multiply(1, 2));
// ES6
import {name, age, height} from "./info";
console.log(name);
console.log(age);
console.log(height);
重新打包之后可以在控制台看到打印的内容。