1.webpack 的介绍
1.1 什么是webpack
webpack 是一个现代的 JavaScript 应用程序的模块打包器(module bundler) ,分析你的项目结构,找到JavaScript模块以及其他的一些浏览器不能直接运行的拓展语言(Sass TypeScript等),并将其打包转换为合适的格式供浏览器使用。
1.2 为什么需要webpack
一个程序往往以来很多模块,或者编译scss less 等如果依赖人工管理不太可能,这个时候我们就必须依赖webpack来解决。
2. webpack 的安装
注意: 请先安装 node 环境
然后通过命令 npm install [email protected] -g 来安装webpack
这里建议安装一下 nrm (方便随时切换镜像源)
1. win + r 打开运行窗口,输入cmd,打开命令窗口
2. 命令 npm install nrm -g 来安装nrm
3. 通过 nrm ls 来查看镜像源
4. 通过 nrm use +镜像名 来切换镜像源,如 选择淘宝 nrm use taobao
效果图如下:
3. 使用webpack
文件打包命令: webpack 输入文件路径(要打包的文件) 打包好的文件路径 这样就把一个文件打包成另一个文件
示例如下:
新建一个JS文件为test1.js内容为:
function add (a, b) { return a + b } //用ES6语法 将add 函数暴露出去 module.exports = add;
又建一个js 文件 为test2.js 内容为:
//引入test1.js const add = require('./test1') document.write(add(1,1)) //传参(1,1)通过引入的函数打印值
新建一个HTML文件,名为text.html,并且引入test2.js
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>测试</title> 8 <script src="./test2.js"></script> 9 </head> 10 <body> 11 12 </body> 13 </html>
结果: 正常情况下 ,HTML页面应该打印出值2, 即test2.js的结果 ,但是由于两个JS文件都是用的ES6语法,浏览器无法解析,这时就需要webpack来转换打包
命令窗口:
此时,会额外生成一个JS文件。为index.js文件,然后在test.html中引入index.js文件 页面中显示打印的结果 2
4. webpack 中 loader 的配置和使用
4.1 webpack-config
注意: 上述案例中,每当我们改变test2.js 文件中的实参数值时, 我们都需要通过重复执行命令 webpack ./test2.js ./index.js 。 这样工作将会十分繁琐,为此,我们来配置一下 webpack-config
配制方法: 1. 新建文件 webpack-config.js
2. 通过mudule.exports 暴露一个对象,在对象中配置入口文件和输出文件 ,代码如下
1 //引入path 模块 2 const path = require('path') 3 module.exports = { 4 //配置入口文件 即要打包的文件 5 entry: './src/test2.js', 6 //配置输出文件 7 output: { 8 //path 表示输出文件的路径 这使用node中 path.join 路径拼接方法 dist表示在当前文件夹下再创建一个dist文件夹 9 path: path.join(__dirname, 'dist'), 10 //filename: 表示输出文件的名称 11 filename: 'bundle.js' 12 } 13 }
3. 运行命令: webpack。创建出一个新的文件夹,里面包含有打包好的文件bundle.js. 然后将此JS 文件引入到test.html 中,代替其中的index.js 文件。
4.2 webpack-dev-server (实现:当改变test2.js文件中的值是,在我们保存之后 系统自动给打包并且自动打开浏览器)
默认为 inline 模式(浏览器自动刷新)
配置步骤:
1. 运行 npm init -y 会生成一个package.json的文件
2. 运行 npm i [email protected] [email protected] -D -D意思是安装到项目依赖,是-save-dev的简写 -S是-save的简写
1 //引入path 模块 2 const path = require('path') 3 module.exports = { 4 //配置入口文件 即要打包的文件 5 entry: './src/test2.js', 6 //配置输出文件 7 output: { 8 //path 表示输出文件的路径 9 path: path.join(__dirname, 'dist'), 10 //静态资源在服务器上运行时的访问路径,可以直接http://localhost:8080/dist/bundle.js访问到服务器中的bundle.js文件 11 publicPath: '/dist', 12 //filename: 表示输出文件的名称 13 filename: 'bundle.js' 14 } 15 }
3. test.html 中修改script 的src 路径文件 <script src="./dist/bundle.js"></script> 为 <script src="/dist/bundle.js"></script>,即去掉 '/dist' 前面的点,成为绝对路径
4. 运行: webpack- dev-server
页面效果: 说明编译成功
5.运行: webpack-dev-server --inline --hot --open --port 8080
打印出结果
6. 配置script 使浏览器自动启动打开,并且在数据更改后自动更新。 打开package.json文件,找到script,把里面的默认内容替换为"dev" : "webpack-dev-server --inline --hot --open --port 8080" 如下:
{ "name": "3-webpack-dev-server", "version": "1.0.0", "description": "", "main": "webpack.config.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" 改为: "dev" : "webpack-dev-server --inline --hot --open --port 8080" }, "keywords": [], "author": "", "license": "ISC" }
7. 运行: npm run dev
浏览器自动启动而且打印经过webpack打包好的文件的值
5. webpack-css
5.1 webpack-css 当我们在项目中新建一个样式文件 如:a.css ,并且采用ES6的语法将样式文件引入index.html文件中,require('样式文件的路径'),而不是用link引入
代码如下:
1 //引入test3.js 2 const add = require('./test3') 3 document.write(add(2,8)) //传参(1,1)通过引入的函数打印值 4 //使用ES6语法 引入a.css文件 5 require('../style/a.css')
页面效果: 但是当我们再次运行 npm run dev 时,并不能成功打包,而且样式也没有应用成功,并且报错,如下
5.2 安装css处理包 命令: npm install css-loader style-loader --save-dev
配置解析css文件的loader,在webpack.config.js文件中配置,使用module,一个对象,里面是rules,一个数组,数组里面一个是 test属性,使用正则表达式来匹配当前的文件,一个是use数组,里面是加载的解析包 即css-loader和style-loader
1 module: { 2 rules: [ 3 //配置用来解析css文件的loader(css-loader style-loader) 4 {test: /\.css$/, //用正则匹配当前访问的文件的后缀名是 .css 5 use: ['style-loader', 'css-loader'] // webpack底层调用这些包的顺序是从右到左 6 } 7 ] 8 }
5.3 整体示例代码如下:
html文件:index.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>测试</title> 8 <script src="/dist/bundle.js"></script> 9 </head> 10 <body> 11 <div class="css">这里的文字样式并没有使用link引入样式文件,而是使用的ES6语法,在test4.js引入</div> 12 </body> 13 </html>
样式文件:a.css
.css { color: #f00; }
配置文件:webpack.config.js
1 //引入path 模块 2 const path = require('path') 3 module.exports = { 4 //配置入口文件 即要打包的文件 5 entry: './src/test4.js', 6 //配置输出文件 7 output: { 8 //path 表示输出文件的路径 9 path: path.join(__dirname, 'dist'), 10 //静态资源在服务器上运行时的访问路径,可以直接http://localhost:8080/dist/bundle.js访问到服务器中的bundle.js文件 11 publicPath: '/dist', 12 //filename: 表示输出文件的名称 13 filename: 'bundle.js' 14 }, 15 module: { 16 rules: [ 17 //配置用来解析css文件的loader(css-loader style-loader) 18 {test: /\.css$/, //用正则匹配当前访问的文件的后缀名是 .css 19 use: ['style-loader', 'css-loader'] // webpack底层调用这些包的顺序是从右到左 style-loader作用是在HTML中创建style标签 css-loader是解析css文件 20 } 21 ] 22 } 23 }
引入的文件:test4.js
//引入test3.js
const add = require('./test3')
document.write(add(2,8)) //传参(1,1)通过引入的函数打印值
//使用ES6语法 引入a.css文件
require('../style/a.css')
页面效果:
6. webpack-less / webpack-sass
6.1在HTML页面中加入使用 b.less和 c.scss文件的元素
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>测试</title> 8 <script src="/dist/bundle.js"></script> 9 </head> 10 <body> 11 <div class="css">这里的文字样式并没有使用link引入样式文件,而是使用的ES6语法,在test4.js引入</div> 12 <div class="less">这里应用了less</div> 13 <div class="scss">这里应用scss</div> 14 </body> 15 </html>
6.2 新建 b.less 和 c.scss 样式文件,并且写入样式
6.3 在test4.js中,使用ES6 语法 分别引入 b.less 和 c.scss
1 //引入test3.js 2 var add = require('./test3') 3 document.write(add(2,8)) //传参(1,1)通过引入的函数打印值 4 5 require('../style/a.css') //使用ES6语法 引入a.css文件 6 require('../style/b.less') //使用ES6语法 引入b.less文件 7 require('../style/c.scss') //使用ES6语法 引入c.sass文件
6.4 按装解析 less 和 scss 文件的loader
lessd的loader 命令:npm install less less-loader --save-dev 是依赖安装
scss的loader 命令: npm install sass-loader node-sass --save-dev 同样是依赖安装
6.5 在webpack.config.js中配置解析 less 和 scss 的 loader,配置方式如下:
6.6 页面效果;
7. webpack-image/webpack-fonts
7.1为引用了.css的元素添加背景图片,代码如下:
7.2 下载安装图片和文件的加载 loader
命令: npm install file-loader url-loader --save-dev 这其中url-loader中包含了file-loader
7.3 在 webpack.config.js 中的 module 对象中配置图片和字体的 loader
7.4 运行: npm run dev 页面效果:
7.5 应用字体图标示例:
步骤:
7.5.1 打开网址 icomoon.io 字体图标网站,点击左上角IcoMoon App 按钮,随便选择一个字体图标,点击右下角的Generate Font 按钮,在点击同样位置的download按钮,下载字体图标。 然后解压下载的文件,把fonts文件夹复制到项目中的根目录,style.css文件复制到项目的style文件夹中。
7.5.2 把字体样式通过test4.js引入
7.5.3 由于字体图标和图片使用的一样的文件loader即file-loader和url-loader 所以这里不再下载,但是需要配置一下,方法是将字体文件的后缀名写在配置图片文件格式之后即可,如下
7.5.4 运行命令 npm run dev .页面效果如下:
8. webpack-html 、 webpack-babel
webpack-html 的使用 (插件--- html-webpack-plugin)
问题: 当我们修改webpack.config.js 文件中output 的filename时,就需要修改HTML中的引入的文件,这样会比较繁琐,这是就需要一个插件 html-webpack-plugin
应用该插件的步骤:
1. npm install html-webpack-plugin --save-dev
2. 在webpack.config.js文件中,使用ES6语法引入 HtmlWebpackPlugin插件 var HtmlWebpackPlugin = require('html-webpack-plugin')
3. 配置插件 注意:应用该插件时,需要将output的publicPath属性删除,否则会造成冲突
1 //引入path 模块 2 const path = require('path') 3 //引入html-webpack-plugin插件 4 var HtmlWebpackPlugin = require('html-webpack-plugin') 5 module.exports = { 6 //配置入口文件 即要打包的文件 7 entry: './src/test4.js', 8 //配置输出文件 9 output: { 10 //path 表示输出文件的路径 11 path: path.join(__dirname, 'dist'), 12 //静态资源在服务器上运行时的访问路径,可以直接http://localhost:8080/dist/bundle.js访问到服务器中的bundle.js文件 13 // publicPath: '/dist', 14 //filename: 表示输出文件的名称 15 filename: 'bundle.js' 16 }, 17 module: { 18 rules: [ 19 //配置用来解析css文件的loader(css-loader style-loader) 20 { 21 test: /\.css$/, //用正则匹配当前访问的文件的后缀名是 .css 22 use: ['style-loader', 'css-loader'] // webpack底层调用这些包的顺序是从右到左 23 }, 24 //配置用来解析less文件的loader(less less-loader) 25 { 26 test: /\.less$/, 27 use: ['style-loader', 'css-loader', 'less-loader'] 28 }, 29 //用来配置解析scss文件的loader(sass-loader node-sass) 30 { 31 test: /\.scss$/, 32 use: ['style-loader', 'css-loader', 'sass-loader'] 33 }, 34 //配置图片和字体的loader (file-loader url-loader) 35 { 36 test: /\.(png|jpg|gif|eot|svg|ttf|woff)/, 37 use: [{ 38 loader: 'url-loader', //url-loader中封装了file-loader 39 options: { //limit表示如果图片大于1000byte,就以路径形式展示(用file-loader),小于的话就用base64格式 展示(用url-loader) 40 limit: 1000 41 } 42 }] 43 } 44 ] 45 }, 46 plugins: [ 47 new HtmlWebpackPlugin({ //这里意思是根据一个template。HTML模板文件 生成一个新的HTML文件 48 filename: 'index.html', 49 template: 'template.html' 50 }) 51 ] 52 }
4. 将原来HTML文件中的script 标签删除。 即删除:<script src="/dist/bundle.js"></script>
5. 运行 npm run dev
webpack-babel 的使用: loader---(babel-core babel-loader babel-preset-env) 它是专门处理ES6语法的
注意:webpack 1.x ----> babel-loader 6.x webpack 2.x ----> babel-loader 7.x (推荐) webpack 3.x ----> babel-loader 7.1
步骤:
1. 安装包 命令: npm install babel-core babel-loader babel-preset-env --save-dev
2. 修改test3.js 将其改为ES6语法 同时修改test4.js也用ES6语法引入test3.js
3. 配置babel-loader
1 { 2 test: /\.js$/, 3 //webpack2建议尽量使用include 避免使用exclude。 exclude:/(node_modules)/ //node_modules下面的JS文件会被排除 4 include: [path.resolve(__dirname, 'src')], 5 use: { 6 loader: 'babel-loader', 7 //option里面的东西可以放到一个新建文件 .banelrc 的文件中 8 option: { 9 presets: ['env'] //babel-loader 的版本 10 } 11 } 12 }
4. 运行 npm run dev . 页面正常显示 说明es6语法被插件成功编译 并且交给浏览器成功的解析。
注意: 配置中的option 属性的内容可以单独的抽离到一个 .babelrc的文件中 如下图: