webpack是什么
是一个模块打包器
模块化历史
- CommonJS
//moduleA.js
exports.a = 1
//moduleB.js
var moduleA = require('./moduleA')
- AMD
// moduleA.js
define (function(){
return {
name: A
}
})
// moduleB.js
require(['./moduleA'], function(moduleA){
console.log(moduleA.name)
})
- ES6 Modules
//moduleA.js
let name = 'A'
let age = 18
export name
export age
//ES6中,export和import是关键字,使用这两个可以输出和引入模块
// moduleB.js
import name from './moduleA'
console.log(name)
Get started
- webpack默认支持CommonJS、AMD、ES Modules
webpack.config.js学习
config.js是node的文件,浏览器是看不到的,只有开发者看得到
-
配置文件的写法
说明:有了配置文件,就可以直接运行webpack,然后根据你配置的入口和输出位置来进行文件的打包,就不用像前面那样写一长串的命令行来指定要打包的文件,和输出的位置。
-
运行配置文件
说明:这里只写webpack就能实现效果是因为有两个默认:1. 输入webpack,node会默认在当前目录的node_modules下寻找webpack工具包。 2. webpack会默认在当前目录下寻找webpack.config.js来作为它的配置文件。 因为有这两个默认的存在,可以直接通过webpack命令实现效果。
-
引入变量
在ES6中,如果对象中的变量为name:name,那么可以直接写name作为对象中的变量
加载css
-
直接在文件中引入css文件
结果报错
原因:webpack不知道如何处理css -
通过加载loaders来加载css的处理模块
-
为什么js可以加载css
-
webpack使用autoprefixer-loader
加载图片
1.配置图片处理loaders
2.缺少模块,进行安装
3.安装缺少的模块后,继续build,产生图片
压缩图片
-
配置压缩工具
-
压缩完成后
webpack --watch
-
作用:使用watch后,会监视文件是否发生改动,每次发生改动,都会自动build一次,就不用自己输代码了
在scripts中配置命令方便使用
webpack 引用scss文件
-
引入scss文件
-
通过搜索loaders找到使用方法,在配置文件中写好loaders
-
安装loader
-
执行build
提示缺少模块
安装node sass
node sass是ruby社区发明的,但是node并没有完全重写这个模块,所以安装时有些注意事项
- 直接安装,开始前面的部分都正常,但最后有个地方有个文件的下载需要指定位置
git bash中运行这一行代码指定下载位置export SASS_BINARY_SITE="https://npm.taobao.org/mirrors/node-sass"
,然后再进行npm install node-sass来安装模块才能成功
- less的loader的安装方法相同,有了这些后,甚至可以在项目中实现less和sass的混写
webpack Dev Server(自动刷新工具)
webpack-dev-server如果是3.x的话,webpack必须是4.x才不会报此TypeError: Cannot read property 'compile' of undefined错误, 同理如果webpack是3.x,则webpack-dev-server必须是2.x
安装
npm install webpack-dev-server --save-dev
-
运行webpack dev server
出现提示,项目在localhost8080下运行,此时打开这个地址,就能预览页面
查看请求
修改css,查看是否能自动刷新并查看效果
解决前面出现的不能刷新效果的问题
原因:首先,原因是我们访问的是dist目录,而其中的index.html引用的是dist目录下的bundle.js,这个文件是死的,也就是我们在修改css文件后,这个js文件是没有被重新build的,而根目录(也就是localhost:8080下)下的bundle.js是动态的,是活的,所以我们要引用这个js-
引用根目录下的bundle.js
下图这种写法是在引用dist目录下的bundle.js,这个文件是死的。为什么呢?其实现在8080根目录下和dist目录下都有bundle.js,但是dist下的那个是死的,8080下这个是动态的,因为devserver会默认将你所有的静态资源都能在8080下访问到,只有一个bundle.js是动态的
下图这种写法在引用8080根目录下的bundle.js
-
引用dist目录下的bundle.js
总结:webpack-dev-server其实是会默认将当前目录的所有静态文件放到localhost下,但只有一个文件是动态的,就是默认的根目录下的bundle.js,所以需要引用localhost下的bundle.js,但是我们可以通过配置来实现依赖那个js文件
-
没有指定入口文件,需要自己点选
-
自己配置入口
配置文件中的写法和位置
这时修改文件后的自动刷新可以看见效果
webpack插件学习
自动生成HTML插件
-
步骤
1.先在配置文件中引入两个插件
2.git安装两个插件
3.语法
4.删除dist中的index.html
5.启动webpack-dev-server
注意,这里使用了一个打开网页的插件,url的端口号要和dev-server配置的端口号一样
5.效果
执行webpack-dev-server后,会自动新建一个服务器,然后编译代码,然后打开网页
-
没有index.html,哪来的网页?
功劳其实来自刚刚的两个插件
webpack代码部署、发布
依赖的命令行
webpack -p
-
步骤
1.运行webpack -p
,生成html和js文件
2.git push上传代码
3.github上开启预览页面,实现预览 -
发布后效果
代码体积大大减小
几个补充
-
回到最开始,webpack其实就是个打包器,就像刚刚上面所实现的,将所有东西,图片、js、css、html都打包成一个bundle.js,然后这些东西通过一个文件放到页面上。还有另一个概念,就是为模块化而生的打包器,就像我们刚刚生成的bundle,就是一个模块,它内部有自己的逻辑,也就是各个文件之间的逻辑,不受别人影响,也不影响别人,就是一个独立的模块,这样就让我们的代码条理清晰,不会出现写一个1000代码的js,而是10个100行代码的js。
-
bundle.js有问题
这时的bundle.js还是从缓存中获取的,如果我们升级了呢?那用户还是用的旧的,所以应该加个哈希,让用户能保持最新的代码来使用
添加步骤
1.在配置文件中输出的bundle.js后加上-[hash]
2.执行webpack -p,发现bundle.js多了哈希
3.修改文件,重新压缩,bundle.js的哈希也会发生变化
这样一来,用户既能快速访问旧的功能,但同时又能保持新的功能的更新
-
为什么要自动生成html
因为html引用的js是最新build的,如果自己维护,根本不知道哈希已经变成什么了
如果想在自动成的html中加东西怎么办?例如,我想加个meta,这个是有选项的,可查阅文档实现