webpack中文官方网站:webpack 中文文档 | webpack 中文网
一、webpack发展由来
前面介绍的几种模块化方案中,所有的模块都需要从服务器端传输到浏览器,那么这个过程有两种情况:
1、一个请求得到一个模块
优点:只有需要的模块被传输。缺点:多个请求意味着占用更多带宽,请求延迟导致应用启动很慢。
2、一个请求得到所有模块
优点:更少的请求,更少延迟。缺点:不需要的模块也被下载。
webpack的出现是为了解决以上模块化的一些缺陷,主要是三个方面:
1、公共的模块(能够复用的打包成一个)+单个用的模块(不能复用的单独打包)
2、webpack本身只能处理.js模块,但是可以通过插件实现打包处理其他类型文件,如css、图片等
3、加载模块时,实现动态分析,只加载需要使用的js
二、webpack 安装配置
首先创建一个空目录webpacktest(不能是汉字或特殊关键词如webpack), 命令行进入该目录,输入
npm init
2.1 安装webpack 及 webpack-cli
(如果安装有问题可以删除。删除命令:npm uninstall webpack -g 最好项目目录下的node-modules一起删除,否则会有残留文件影响下一次的结果,还有C:\Users\samsung\AppData\Roaming\npm\ 里面所有webpack的东西都删除)
npm i webpack webpack-cli --save-dev
注意:直接在vscode终端输入命令可能出现“npm ERR! Error: EPERM: operation not permitted, mkdir ...” 问题。权限不够导致,请在windwos的命令行窗口执行
安装完成后,修改 package.json中的配置项:
"scripts": { "dev" : "webpack --mode=development" },
2.2 初始化(入口文件 index.js)
创建文件夹 src ,里面创建index.js文件,随便写的什么内容
const fn=()=>{ console.log('首页 init') } fn()
根目录下创建webpack.config.js文件,输入以下内容:
const path = require("path"); //path是node的模块,获取当前文件的路径 module.exports = { entry: { index: "./src/index.js" //入口文件,若不配置webpack4将自动查找src目录下的index.js文件 }, output: { filename: "[name].bundle.js",//输出文件名,[name]表示入口文件js名 path: path.join(__dirname, "public")//输出文件路径 } }
命令行执行
npm run dev
将会生成 public/index.bundle.js
接下来src目录下创建一个index.html文件,引入刚才打包好的文件。打开页面,可以看到js执行效果。
接下来,再创建a.js 和 common.js。a.js中导入了common.js,即a依赖于common
common.js的代码:
let name = "张三"; export default { name }
a.js 中的代码
import common from "./common"; let fn = function(){ console.log( common.name ); } export default { fn }
index.js中修改为:
import common from "./common"; import a from "./a"; let fn = ()=>{ console.log("hello world!"); console.log( common.name ); a.fn(); } fn();
再次执行 npm run dev,webpack将所有形成依赖关系的js打包为一个index.bundle.js。这里即体现了webpack的基本功能。
2.3 CSS文件打包插件及配置
创建 style.css,并导入到index.js中。
style.css的内容:
body{ background-color: #6b0392; }
在index.js中添加一行:
import './style.css'
执行打包命令 npm start;如果模块中引入了css文件,如果没有css的打包插件会出现如下错误提示:
安装 css打包插件:
npm i [email protected] style-loader -D
(注意:经测试,需要安装指定版本的css-loader, 否则后面会出现兼容性问题)
安装完成以后,查看package.json文件,会自动添加:
然后在webpack.config.js中增加css插件的配置项:
// webpack的相关插件配置项: module:{ rules:[ {test:/\.css$/,use:['style-loader','css-loader']} //处理.css文件 ] }
执行打包命名 npm run dev;可以看到css生效。
2.4 CSS中的图片处理
在style.css中添加图片,其中home.gif 文件小于8k:
body { background-color: sandybrown; background-image: url(img/home.gif); } .logo { width: 200px; height: 200px; background-image: url(img/logo.jpg); }
在index.html 中添加如下html代码
图片的处理需要 file-loader和url-loader,先安装
npm i file-loader url-loader -D
然后在webpack.config.js中的添加配置:注意要有逗号分隔
module:{ rules:[ {test:/\.css$/,use:['style-loader','css-loader']}, //处理.css文件 { test:/\.(png|gif|jpg)$/, use:[ { loader:'url-loader', options:{ outputPath:'images/', limit:8192 // 小于 8k 的图片自动转成 base64 格式 } } ] } ] }
执行 npm run dev后查看打包效果。可看到图片已被正确打包,小于8k的图片自动转为base64编码。大的图片放在public/images 目录下。但标签里的图片还是src目录下,接下来我们将index.html文件也进行打包。
.2.3 index.html模板文件处理(html-webpack-plugin)
该插件的作用是自动生成index.html模板文件,并自动的写入 打包后的js文件;当入口文件的文件名不固定时特别有用。
首先修改webpack.config.js
重新打包后发现变成了index.bundle.fce06d10db1c477cf839.js ,每次都会不一样,这样做是为了避免缓存问题。但是每次都要将html中的引入js文件也要自动替换。
先安装:
npm i html-webpack-plugin -D
再配置:
首先要引入插件,在webpack.config.js的开头添加:
const HtmlWebpackPlugin = require('html-webpack-plugin');
配置插件:
plugins: [ new HtmlWebpackPlugin({ template:'./src/index.html' //参照物,从这儿移动复制到output指定的目录下 }) ]
书写位置如下:
打包后public 目录下会增加一个index.html;并且打包后的 js 文件自动注入了。但是标签的中图片因为路径原因看不到了。需要新的插件解决这个问题
2.4 HTML 中图片的引用处理
安装 htmlwithimg-loader 模块
安装:
npm i html-withimg-loader -D
添加配置:
{
test: /\.(htm|html)$/,
use: 'html-withimg-loader'
}
运行 npm run dev ,显示打包错误:
需要增加一个publicPath属性:
继续打包,仍会报告错误:
这是因为它和html-webpack-plugin产生冲突;
原因是file-loader升级了,所以需要在url-loader的options里使用一个配置:
esModule:false
这样就解决了
此时检查public/index.html ,可以看到中的图片也打包成功了。
2.5 清除指定目录插件 clean-webpack-plugin
安装:
npm i clean-webpack-plugin --save-dev
配置:
在在webpack.config.js的开头添加:
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
然后在下面添加:
如果在 vscode 中执行 npm run dev , 此时可能会因为删除文件权限问题出现如下报错:
换成管理员方式打开命令行窗口则可以成功执行:
2.6 less插件
安装:需要两个模块less 和 less-loader
npm i less less-loader -D
配置:
// less的配置项 { test: /\.less$/, use: [{ loader: "style-loader" }, //创建