webpack搭建项目基础篇
一.创建项目
首先在终端cd到你的项目根目录,使用npm init创建package.json文件,
在你创建好的package.json文件里面的scripts字段那里新增这样一行,配置一下webpack执行的文件路径,同时创建一下webpack.config.js文件放在项目根目录下面
我们使用yarn add webpack webpack-cli安装一下webpack和webpack-cli两个依赖 (没有安装yarn的话可以使用npm或者cnpm,当然建议使用yarn会快一点)
二.模拟项目需要的文件
在src文件下面创建文件如下:
1.模拟接口请求事件
2.创建入口文件
3.创建一个scss文件
样式可以随便写,这边只是模拟一下
4.创建一个html文件
三.配置webpack
我们在webpack.config.js文件里面配置webpack的内容,需要配置entry、output、module、mode、plugins、optimization(分别对应的是:入口、输出、模块、模式、插件、优化)
其中require引进去的,基本都需要用yarn下载下来。path除外
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const CompressionPlugin = require("compression-webpack-plugin");
const HtmlMinimizerPlugin = require("html-minimizer-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const webpack = require('webpack'); // 访问内置的插件
这里配置一下入口文件和输出的配置,入口的路径为src里面的index文件,输出文件这里用了文件名拼接哈希值,主要是避免文件打包发布服务器之后用户任然读取到旧文件的情况。output里面设置arrowFunction: false,主要是让打包完的函数不要返回箭头函数,否则部分浏览器不兼容。
entry: {
index: './src/index.js'
},
output: {
filename: '[name]_[hash].js',
path: path.resolve(__dirname, 'dist'),
environment: {
arrowFunction: false, //true默认箭头函数
}
},
处理sass\scss文件
由于我们引入了scss预编译css文件,所以我们需要安装一下sass-loader、css-loader,style-loader这几个依赖。
{
test: /\.s[ac]ss$/,
use: [
'style-loader',//注入到head里面新增一个style标签生成样式
'css-loader',
'sass-loader'
]
},
test是匹配规则,采用正则表达式语法,use是需要的loader,执行顺序又下到上所以sass-loader需要写在最底部(具体内容可以查看webpack的sass-loader配置)
处理js文件
js需要用到babel-loader做处理,需要安装一下@babel/core、babel-loader、@babel/preset-env。@babel/preset-env可以将es6语法转为es5比如let、const这些,否则部分浏览器不兼容
{
test: /\.(js|jsx)$/,
// use:'babel-loader',
use: {
loader: 'babel-loader',
// es6转es5
options: {
exclude: 'node_modules',
presets: [
[
"@babel/preset-env",
{
"modules": false
}
]
]
}
},
},
具体可参考@babel/preset-env · Babel 中文网
处理html文件里面引入的图片
由于我们的图片再html文件内容引入,但是默认是打包入口文件里面导入的图片,所以如果我们不在入口文件引入直接在html文件内部引入的话我们需要额外用html-loader去处理
<div id="app">
<div>1234444444</div>
<img src="./static/again_btn.png" alt="">
</div>
需要安装一下 html-loader和url-loader
{
// 用来处理html里面img引入的图片(负责引入img,从而能被url-loader处理)
test: /\.html$/,
use: [
{
loader: 'html-loader',
options: {
// Disables attributes processing
sources: true,
},
},
],
generator: {
filename: "[name][ext]",
},
},
处理字体文件
// 处理字体文件
{
test: /\.(woff2|eot|svg|ttf|woff)$/,
loader: 'url-loader',
options: {
// 图片大小处理,limit:30*1024表示小于30kb就会被处理成base64
// 优点:变少请求数量,减轻服务器压力
// 缺点:图片体积会更大(文件请求速度更慢)
limit: 3 * 1024,
esModule: false,
// 给图片进行重命名
// [hash:10]取图片的hash的前10位
// [ext]取文件原来的扩展名
name: '[name]_[hash].[ext]'
// 打包图片的时候同一份图片只会打包一次
}
},
处理index.js里面引入的图片
这里采用file-loader,当然也可以采用url-loader去处理。如果是在html里面引入图片路径的话,这里的配置可以忽略
// 处理图片
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
options: {
name: 'static/img/[name]_[hash].[ext]',
// 问题:由于url-loader默认使用es6模块化解析,而html-loader引入的图片是commonjs
// 解析时会出现问题:<img src="[object Module]" alt="webpack-img">
// 解决:关闭url-loader的es6模块化,使用commonjs解析
esModule: false,
},
},
],
},
配置一下plugins
plugins: [
// 清除之前打包的内容
new CleanWebpackPlugin(),
// 打包进度
new webpack.ProgressPlugin(),
// 文件压缩
new CompressionPlugin({
test: /\.js(\?.*)?$/i,
}),
// 打包某个html文件
new HtmlWebpackPlugin({
template: './src/index.html',//拷贝的html文件
inject: "body",//打包好的js插入位置
scriptLoading: "blocking"//加载是否阻塞
}),
],
HtmlWebpackPlugin的配置具体可以参考GitHub - jantimon/html-webpack-plugin: Simplifies creation of HTML files to serve your webpack bundles
最后配置一下optimization
压缩一下html文件
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin(),
],
}
完整配置如下
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const CompressionPlugin = require("compression-webpack-plugin");
const HtmlMinimizerPlugin = require("html-minimizer-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const webpack = require('webpack'); // 访问内置的插件
const path = require('path');
const config = {
entry: {
index: './src/index.js'
},
output: {
filename: '[name]_[hash].js',
path: path.resolve(__dirname, 'dist'),
environment: {
arrowFunction: false, //true默认箭头函数
}
},
module: {
rules: [
{
// 用来处理html里面img引入的图片(负责引入img,从而能被url-loader处理)
test: /\.html$/,
use: [
{
loader: 'html-loader',
options: {
// Disables attributes processing
sources: true,
},
},
],
generator: {
filename: "[name][ext]",
},
},
// babel-polyfill已经被移除了
{
test: /\.(js|jsx)$/,
use: {
loader: 'babel-loader',
// es6转es5
options: {
presets: [
[
"@babel/preset-env",
{
"modules": false
}
]
]
}
},
},
{
test: /\.s[ac]ss$/,
use: [
'style-loader',//提取到单独文件需要结合 optimization配置
'css-loader',
'sass-loader'
]
},
// 处理字体文件
{
test: /\.(woff2|eot|svg|ttf|woff)$/,
loader: 'url-loader',
options: {
// 图片大小处理,limit:30*1024表示小于30kb就会被处理成base64
// 优点:变少请求数量,减轻服务器压力
// 缺点:图片体积会更大(文件请求速度更慢)
limit: 3 * 1024,
esModule: false,
// 给图片进行重命名
// [hash:10]取图片的hash的前10位
// [ext]取文件原来的扩展名
name: '[name]_[hash].[ext]'
// 打包图片的时候同一份图片只会打包一次
}
},
// 处理图片
// {
// test: /\.(png|jpe?g|gif)$/i,
// use: [
// {
// loader: 'file-loader',
// options: {
// name: 'static/img/[name]_[hash].[ext]',
// // 问题:由于url-loader默认使用es6模块化解析,而html-loader引入的图片是commonjs
// // 解析时会出现问题:<img src="[object Module]" alt="webpack-img">
// // 解决:关闭url-loader的es6模块化,使用commonjs解析
// esModule: false,
// },
// },
// ],
// },
],
},
mode: "production",
plugins: [
// 清除之前打包的内容
new CleanWebpackPlugin(),
// 打包进度
new webpack.ProgressPlugin(),
// 文件压缩
new CompressionPlugin({
test: /\.js(\?.*)?$/i,
}),
// 打包某个html文件
new HtmlWebpackPlugin({
template: './src/index.html',//拷贝的html文件
inject: "body",//打包好的js插入位置
scriptLoading: "blocking"//加载是否阻塞
}),
],
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin(),
],
}
};
module.exports = (env, argv) => {
return config;
}
最后执行npm run build
如果出现这样的结果代表已经打包成功,如果提示错误的话可能是某个依赖没有安装,可以参考一下我的package.json里面安装dependencies和devDependencies的依赖
webpack是依赖于node.js处理的工具,所以我们首先node和npm,具体可以百度上下载安装。