webpack
1. webpack介绍
在传统的项目中,一个html文件可能会加载多个js、css文件,如果多人协同开发的话,就会出现全局变量被污染、文件直接的依赖问题
而webpack打包工具,会先分析入口文件的依赖,以及依赖的依赖,以此类推,只要有依赖都去分析并打包到输出文件中
例:app.js中需要cat.js,webpack就会将这些依赖分析之后,打包到bundle.js文件中,以后直接使用打包好的bundle.js文件
2. webpack安装
- 全局安装:
cnpm install webpack webpack-cli –g
- 建议本地也安装一次:
cnpm install webpack webpack-cli --save-dev
例:在cat.js中导出一个数组,App.js 中需使用 cat.js 文件中的数组,需要require()加载
cat.js 代码
let cats = ['黑猫警长','大脸猫','波斯猫'] module.exports = cats
app.js 代码
//加载 cat.js 导出的数组 const cats = require("./cat") console.log(cats)index.html 代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script type="text/javascript" src="app.js"></script> </head> <body> </body> </html>在浏览器中访问:
注:前提先安装好 webpack
解决方法:webpack会分析 app.js 文件中的依赖,并找到依赖的文件,将最终的代码打包到一个文件中。输入命令:
webpack app.js –o bundle.js打开目录,其中有创建好的 bundle,js 文件,在 index.html 文件中直接使用该文件
打开浏览器重新运行
3. webpack 使用流程
- 先搭建目录结构
- 初始化 package.json
npm init -y
注:-y表示创建一个默认的 package.json 文件
- 安装webpack
- 全局安装
cnpm install webpack webpack-cli –g
-
- (建议)本地也安装一次:
cnpm install webpack webpack-cli –-save-dev
- 搭建基本的目录结构(src:保存源代码;dist:保存编译之后的文件,即打包之后的文件)
- 创建 src 目录下的入口文件,通常取名为:app.js
- 创建 webpack.config.js 配置文件
module.exports = { //告诉 webpack 入口文件 entry: __dirname + "/src/app.js", //打包后的文件输出到哪个目录,即打包后的文件存放目录 output: { path: __dirname + "/dist", filename: "bundle.js"//打包后输出文件的文件名 } }
- 通过 webpack 打包
- app.js 及 app.js 文件的依赖将被打包到 bundle.js,以后直接使用 bundle.js
4. style-loader、css-loader安装
例:若要将 css 文件和 js 文件打包到一起
cat.js 代码
let cats = ['黑猫警长','大脸猫','波斯猫'] module.exports = cats
index.html 代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script type="text/javascript" src="dist/bundle.js"></script> </head> <body> </body> </html>style.css 代码
body{ background-color: blue; }app.js 代码
let cats = require("./cat") require("./style.css") console.log(cats)控制台打包:目前无法解析 css 文件
- 解决方法:安装 style-loader,css-loader
cnpm install style-loader css-loader –-save-dev
- 安装后,还需在webpack 配置文件中添加红色部分的内容:
module.exports = { //告诉 webpack 入口文件 entry: __dirname + "/src/app.js", //打包后的文件输出到哪个目录,即打包后的文件存放目录 output: { path: __dirname + "/dist", filename: "bundle.js"//打包后输出文件的文件名 }, module:{ //定义规则:使用 webpack 打包的文件有哪些 rules:[ { //以.css 结尾的文件 test: /\.css$/, //忽略node_modules目录 exclude: /node_modules/, //多个loader使用!隔开 loader: "style-loader!css-loader" } ] } }
注:逗号很重要!!!后面的打包,我因为没有加这个逗号,而出现错误(设置了 css 文件,代码无错误,控制台打包也无错误,浏览器无错误提示,但就是样式出不来)
- 再次执行webpack 命令进行打包
- 在浏览器中访问 index.html
5. 自动打包
自动打包会监测源码的改动,源码一旦改动,则自动进行打包
5.1 方法一
- 执行后会占用当前窗口,可通过 ctrl+c 关闭该进程
webpack –w
- 测试:修改css代码
body{ background: red; }
- webpack 已自动打包,需要刷新浏览器
5.2 方法二:搭建本地服务器
通过本地服务器,可监测源码的改变并自动打包,且自动刷新浏览器
- 需安装 webpack-dev-server
cnpm install webpack-dev-server –-save-dev
- 在 webpack.config.js 配置文件中配置 webpack-dev-server 服务器的端口信息(红色部分)
module.exports = { //告诉 webpack 入口文件 entry: __dirname + "/src/app.js", //打包后的文件输出到哪个目录,即打包后的文件存放目录 output: { path: __dirname + "/dist", filename: "bundle.js"//打包后输出文件的文件名 }, devServer:{ //端口号 port:8888, //热更新,一旦检测到源码变化,立即刷新 hot:true, inline:true }, module:{ //定义规则:使用 webpack 打包的文件有哪些 rules:[ { //以.css 结尾的文件 test: /\.css$/, //忽略node_modules目录 exclude: /node_modules/, //多个loader使用!隔开 loader: "style-loader!css-loader" } ] } }
- 在 package.json 的 scripts 中添加一个命令:dev(也可用其他名字,如 abc 等)(红色部分)
{ "name": "webpack-demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "dev":"webpack-dev-server --hot --inline", "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "css-loader": "^0.28.11", "style-loader": "^0.21.0", "webpack":"^4.8.3", "webpack-cli":"^2.1.3", "webpack-dev-server": "^3.1.4" } }
- 将来执行自动打包命令时,直接执行如下命令:
npm run dev
注:在 index.html 内引入 bundle.js 文件时,需写 http:// 路径
<script type="text/javascript" src="http://localhost:8888/bundle.js"></script>
6. less-loader安装
less 文件提升 css 的开发效率,但实际运行时需将 less 文件转换成 css文件(less-loader 可完成转换)
- 安装less、less-loader
cnpm install less less-loader –-save-dev
- 修改 webpack.config.js 配置文件(红色部分)
module.exports = { //告诉 webpack 入口文件 entry: __dirname + "/src/app.js", //打包后的文件输出到哪个目录,即打包后的文件存放目录 output: { path: __dirname + "/dist", filename: "bundle.js"//打包后输出文件的文件名 }, devServer:{ //端口号 port:8888, //热更新,一旦检测到源码变化,立即刷新 hot:true, inline:true }, module:{ //定义规则:使用 webpack 打包的文件有哪些 rules:[ { //以.css 结尾的文件 test: /\.css$/, //忽略node_modules目录 exclude: /node_modules/, //多个loader使用!隔开 loader: "style-loader!css-loader" } { test: /\.less$/, exclude: /node_modules/, loader: "style-loader!css-loader!less-loader" } ] } }
测试:
style.less 代码
@c:red; body{ h1{ color:@c } }
app.js 代码
let cats = require("./cat") require("./style.less") console.log(cats)
index.html 代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script type="text/javascript" src="http://localhost:8888/bundle.js"></script> </head> <body> <h1>我是标题</h1> </body> </html>
7. ES6模块化开发
ES6 新增一个模块化开发功能,可将不同功能封装到不同 js 文件中,再通过webpack打包到一起。因有些浏览器不支持ES6语法,故需安装 loader 将 ES6 转换为 JavaScript 代码,命令如下:
cnpm install babel-core babel-loader babel-preset-es2015 babel-preset-stage-2 --save-dev
- 修改webpack.config.js(红色部分)
module.exports = { entry: __dirname + "/src/app.js", output: { path: __dirname + "/dist", filename: "bundle.js" }, devServer:{ port:8888, hot:true, inline:true }, module:{ rules:[ { test: /\.css$/, exclude: /node_modules/, loader: "style-loader!css-loader" }, { test: /\.less$/, exclude: /node_modules/, loader: "style-loader!css-loader!less-loader" }, { test:/\.js$/, loader:"babel-loader", exclude:/node_modules/, query:{ presets:["es2015","stage-2"] } } ] } }
7.1 ES6 导出变量、函数、类
- export let 变量名 导出一个变量
- export function 函数名 导出一个函数
- export class 类名 导出一个类
- export default 成员 导出成员,只能导出一个成员
例:person.js 代码
//导出变量 export let name="David" //导出函数 export function getName(){ console.log("获取姓名") } //导出类 export class Person{
//构造函数 constructor(name){this.name = name; }
//成员方法 say(){ console.log("我是:" + this.name) } } //导出成员 export default class People{ constructor(name){ this.name = name; } say(){ console.log("你好,"+this.name) } }
7.2 ES6 导入变量、函数、类
语法:import {变量名 , 函数名 , 类名 } from ‘文件名’
导入多个成员使用“,”逗号隔开
注:若导出的成员是export default,则导入时,不可使用 {},直接:import 成员
例:app.js 代码
//导入变量、函数、类 import {name,getName,Person} from './person' console.log(name) getName() var people1 = new Person('Mike'); people1.say() //导入成员 import People from "./person" var people2 = new People('Nancy') people2.sayHi()
测试:npm run dev 打包后,浏览器运行:
8. webpack 插件
8.1 内置插件(webpack提供)
BannerPlugin:在 bundle.js 文件的头部插入一条说明性文件
- 修改webpack.config.js 文件(红色部分)
let wp = require("webpack") module.exports = { entry: __dirname + "/src/app.js", output: { path: __dirname + "/dist", filename: "bundle.js" }, devServer:{ port:8888, hot:true, inline:true }, module:{ rules:[ { test: /\.css$/, exclude: /node_modules/, loader: "style-loader!css-loader" }, { test: /\.less$/, exclude: /node_modules/, loader: "style-loader!css-loader!less-loader" }, { test: /\.js$/, loader: "babel-loader", exclude: /node_modules/, query: { presets:["es2015","stage-2"] } } ] }, plugins:[ new wp.BannerPlugin("版权保护") ] }
- 重新打包,运行结果如下:
8.2 外部插件(第三方插件)
执行npm run dev后,自动打开浏览器的插件:open-browser-webpack-plugin。安装命令如下:
cnpm install open-browser-webpack-plugin --save-dev
- 修改webpack.config.js配置文件(红色部分)
let wp = require("webpack") const OpenBrowserPlugin = require("open-browser-webpack-plugin") module.exports = { entry: __dirname + "/src/app.js", output: { path: __dirname + "/dist", filename: "bundle.js" }, devServer:{ port:8888, hot:true, inline:true }, module:{ rules:[ { test: /\.css$/, exclude: /node_modules/, loader: "style-loader!css-loader" }, { test: /\.less$/, exclude: /node_modules/, loader: "style-loader!css-loader!less-loader" }, { test: /\.js$/, loader: "babel-loader", exclude: /node_modules/, query: { presets:["es2015","stage-2"] } } ] }, plugins:[ new wp.BannerPlugin("版权保护"), new OpenBrowserPlugin({url:"http://localhost:8888"}) ] }
- 执行npm run dev,重新打包即可