webpack
写了很多的 js,有一天突然发现自己并不是很清楚 webpack 这个操作原理,所以补上这么一篇记录点滴进步。
webpack帮助文档
webpack菜鸟教程
为什么要使用 webpack ?
核心问题,webpack 有什么用。应该有很多小伙伴写过 js 代码,但是写到那些比较大的页面的时候,就会发生很多的重复,并且产生复用,这种方式叫做 面向过程 的编码,不适合大型项目,难以维护。
// index.js
const element = document.createElement('h2');
element.textContent = 'Hello word';
element.addEventListener('click', () => {
})
所以会转成 面向对象 的编码,即把原来的 js 封装到一个有 function 的类中,在引入到相关 html 的页面中,但是这时,又出现了一个问题。
// helloword.js
function HelloWord() {
const element = document.createElement('h2');
element.textContent = 'Hello word';
element.addEventListener('click', () => {
})
}
export default HelloWord;
// index.js
new HelloWord();
随着封装 js 对象的增加,在 index.html 中引用<script src="./helloword.js></script>"
这种语句会变多,直接导致后台下载量增加,会影响网页相应速度。这时就用到了 webpack,使用 webpack编译后,就可以直接在 index.js 中引入了。
// index.js
import HelloWord from 'helloword.js';
new HelloWord();
同时在这时,就只需要在 index.html 中加载一个 js 文件即可。
webpack.config.js 配置
指示 webpack 干那些活(当你运行 webpack 指令时, 会加载里面的配置),所有构建工具都是基于node.js平台运行的~模块化默认采用commonjs。
注意:我们创建的src文件是我们写项目的源代码,用的是ES6模块化,而wbepack.config.js文件是我们写配置的源代码,默认用的是common.js。
那么如何使用呢?首先在原来的项目中创建一个 webpack.config.js 文件
然后就可以在 webpack.config.js 文件中写配置代码, 代码内容如下:
const path = require('path') // 引用path模块
module.exports = { // 这里是commrnt.js语法
// 入口文件
entry:"./src/index.js",
// 打包后的出口文件
output:{
// 如果需要引入外部的链接上的json文件
publicPath: 'http://cdn.xxx.com',
// 输出的路径 是绝对路径(导入path模块) 这里是用node来做的
path:path.resolve(__dirname,'dist'),
// 输出的文件名称
filename:'main.js',
},
// 使用开发模式打包
mode:"development"
}
loader的使用
webpack 由于可以打包的内容越来越多,比如图片和css代码,但是webpack中默认是不支持js中引入这些内容,就需要用 loader。
在原来的基础上在src文件夹中创建一个css文件,然后在index.js中引入。
const path = require('path') // 引用path模块
module.exports = { // 这里是commrnt.js语法
// 入口文件
entry:"./src/index.js",
// 打包后的出口文件
output:{
// 输出的路径 是绝对路径(导入path模块) 这里是用node来做的
path:path.resolve(__dirname,'build'),
// 输出的文件名称
filename:'build.js',
},
// loader的配置
module:{
rules:[
// 详细loader配置
// 打包css的配置
{
// 使用正则表达式,匹配那些文件
test: /\.css$/,
use:[
// use数组中loader执行顺序, 从右到左, 从下到上, 依次执行
// 创建style标签, 将js中的样式资源插入进行, 添加到head中生效
'style-loader',
// 将css文件变成commitjs模块加载js中, 里面的内容是样式字符串
'css-loader'
]
},
// 打包scss的配置
{
test: /\.scss$/,
// 注意 是sass-loader ,不是 scss-loader
// 是数组,代表的是要使用多个loader处理,用use
use: [
'style-loader',
'css-loader',
// 将scss文件编译成css文件
'sass-loader'
]
},
// 打包图片的配置
{
// 问题:默认处理不了html中img图片
// 处理图片资源
test: /\.(jpg|png|gif)/,
// 使用一个loader时,直接写就行了
loader:'url-loader',
options:{
// 图片大小小于8KB,就会被base64处理
// 优点:减少请求数量(减轻服务器压力)
// 缺点:图片体积会增大, 就会导致文件请求速度更慢
limit: 8 * 1024,
// 问题: 因为url-loader默认使用es6模块化解析,
// 而html-loader引入图片commonjs
// 解析时会出问题: [object Module]
// 解决: 关闭url-loader的es6模块化, 使用commonjs解析
esModule: false,
// 给图片进行重命名
// [hash:10]取图片的hash的前10位
// [ext]去文件原来扩展名
name: '[hash:10].[ext]'
}
},
// 打包 html 的配置
{
test:/\.html$/,
// 处理html文件的img图片 (负责引入img, 从而能被url-loader进行处理)
loader:'html-loader'
}
]
},
// 使用开发模式打包
mode:"development"
}
打包html资源的插件使用
作用:将src的html文件进行打包,在打包完成后在build文件夹中生成一个html文件,并且会对这个html文件做处理,自动帮你把使用的文件引用进去。
然后就可以在 webpack.config.js 文件中写配置代码, 代码内容如下:
const path = require('path') // 引用path模块
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 引入html-webpack-plugin
module.exports = { // 这里是commrnt.js语法
// 入口文件
entry:"./src/index.js",
// 打包后的出口文件
output:{
// 输出的路径 是绝对路径(导入path模块) 这里是用node来做的
path:path.resolve(__dirname,'build'),
// 输出的文件名称
filename:'build.js',
},
// loader的配置
module:{
rules:[
// 详细loader配置
// 打包css的配置
{
// 使用正则表达式,匹配那些文件
test: /\.css$/,
use:[
// use数组中loader执行顺序, 从右到左, 从下到上, 依次执行
// 创建style标签, 将js中的样式资源插入进行, 添加到head中生效
'style-loader',
// 将css文件变成commitjs模块加载js中, 里面的内容是样式字符串
'css-loader'
]
},
// 打包scss的配置
{
test: /\.scss$/,
// 注意 是sass-loader ,不是 scss-loader
// 是数组,代表的是要使用多个loader处理,用use
use: [
'style-loader',
'css-loader',
// 将scss文件编译成css文件
'sass-loader'
]
}
]
},
// plugins的配置
plugins:[
// 详细plugins的配置
// 因为是直接引的,所以 new 就好了
// 功能:默认会创建一个空的HTML文件,自动引入打包输出的所有资源(JS/CSS)
new HtmlWebpackPlugin({
// 复制 './src/index.html'文件,并自动引入打包输出的所有资源(JS/CSS)
// 即以下面的路径文件为模板
template:'./src/index.html'
}),
// 删除已经有的文件
new CleanWebpackPlugin()
],
// 使用开发模式打包
mode:"development"
}
sourcemap
可以快速找到错误代码(打包完的文件)和源文件的对应关系,实现快速的错误查找。
const path = require('path') // 引用path模块
module.exports = { // 这里是commrnt.js语法
// 入口文件
entry:"./src/index.js",
devtool: 'eval-source-map',
// 打包后的出口文件
output:{
// 如果需要引入外部的链接上的json文件
publicPath: 'http://cdn.xxx.com',
// 输出的路径 是绝对路径(导入path模块) 这里是用node来做的
path:path.resolve(__dirname,'dist'),
// 输出的文件名称
filename:'main.js',
},
// 使用开发模式打包
mode:"development"
}
热更新 devServer
通过devServer进行热更新, 代码内容如下:
const path = require('path') // 引用path模块
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 引入html-webpack-plugin
module.exports = { // 这里是commrnt.js语法
// 入口文件
entry:"./src/index.js",
// 打包后的出口文件
output:{
// 输出的路径 是绝对路径(导入path模块) 这里是用node来做的
path:path.resolve(__dirname,'build'),
// 输出的文件名称
filename:'build.js',
},
// loader的配置
module:{
rules:[
// 详细loader配置
// 打包css的配置
{
// 使用正则表达式,匹配那些文件
test: /\.css$/,
use:[
// use数组中loader执行顺序, 从右到左, 从下到上, 依次执行
// 创建style标签, 将js中的样式资源插入进行, 添加到head中生效
'style-loader',
// 将css文件变成commitjs模块加载js中, 里面的内容是样式字符串
'css-loader'
]
},
// 打包scss的配置
{
test: /\.scss$/,
// 注意 是sass-loader ,不是 scss-loader
// 是数组,代表的是要使用多个loader处理,用use
use: [
'style-loader',
'css-loader',
// 将scss文件编译成css文件
'sass-loader'
]
},
{
// 问题:默认处理不了html中img图片
// 处理图片资源
test: /\.(jpg|png|gif)/,
// 使用一个loader时,直接写就行了
loader:'url-loader',
options:{
// 图片大小小于8KB,就会被base64处理
// 优点:减少请求数量(减轻服务器压力)
// 缺点:图片体积会增大, 就会导致文件请求速度更慢
limit: 8 * 1024,
// 问题: 因为url-loader默认使用es6模块化解析,
// 而html-loader引入图片是commonjs
// 解析时会出问题: [object Module]
// 解决: 关闭url-loader的es6模块化, 使用commonjs解析
esModule: false,
// 给图片进行重命名
// [hash:10]取图片的hash的前10位
// [ext]去文件原来扩展名
name: '[hash:10].[ext]'
}
},
{
test:/\.html$/,
// 处理html文件的img图片 (负责引入img, 从而能被url-loader进行处理)
loader:'html-loader'
}
]
},
// plugins的配置
plugins:[
// 详细plugins的配置
// 因为是直接引的,所以 new 就好了
// 功能:默认会创建一个空的HTML文件,自动引入打包输出的所有资源(JS/CSS)
new HtmlWebpackPlugin({
// 复制 './src/index.html'文件,并自动引入打包输出的所有资源(JS/CSS)
template:'./src/index.html'
})
],
// 使用开发模式打包
mode:"development",
// 开发服务器 devServer:用来自动化(自动编译,自动打开浏览器,自动刷新浏览器)
// 用简单概括就是: 热更新
// 特点:只会在内存中编译打包,不会有任何输出
// 启动指令: webpack-dev-server 你也可以在package.json文件中重新修改指令
devServer:{
contentBase:path.resolve(__dirname,'build'),
// 启动gzip压缩
compress:true,
// 修改端口号
port:8080,
//自动打开浏览器
open:true
}
}