Webpack常见面试点总结
为什么需要Webpack,用来干什么
前端不断的技术更新迭代,为了浏览器更好的兼容到以及项目更好的开发,所以才有需要Webpack来打包代码
由于浏览器解析不了es6及以上的语法,无法编译less/sacc等,所以我们需要各种插件去es6编译es5、将less编译成css,比较杂乱,所以就有了webpack将这些插件组合在一起
Webpack 是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。Webpack 可以将多种静态资源 js、css、less 转换成一个静态文件,减少了页面的请求
基本配置
Entry:入口,Webpack执行构建的第一步将从Entry开始,可抽象成输入。
告诉Webpack要使用哪个模块作为构建项目的起点,默认为./src/index.js
output:出口,
告诉Webpack在哪里输出它打包好的代码以及如何命名,默认为./dist
Module:模块,在Webpack里一切皆模块,一个模块对应着一个文件。
Webpack会从配置的Entry开始递归找出所有依赖的模块。
Chunk:代码块,一个Chunk由多个模块组合而成,用于代码合并与分割。
Loader:模块转换器,用于把模块原内容按照需求转换成新内容
Plugin:扩展插件, 在Webpack构建流程中的特定时机会广播出对应的事件,插件可以监听这些事件的发生,在特定时机做对应的事情。
/*
webpack.config.js是webpack的配置文件
作用:告诉webpack干哪些活(运行webpack指令时,会加载里面的配置)
所有的构建工具都是基于nodejs平台运行的,模块化默认采用commonjs
*/
// resolve用来拼接绝对路径的方法
const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
// webpack配置
// 入口文件:指示webpack以哪个文件为入口文件开始打包
entry: './src/index.js',
// 输出
output: {
// 输出文件名
filename: 'built.js',
// 输出路径 __dirname是nodejs的变量,代表当前文件webpack.js目录的绝对路径02打包样式资源
// 输出到build目录下去
path: resolve(__dirname, 'build')
},
// loader的配置(1.下载2.使用)
module: {
rules: [
{
// test:使用正则匹配文件
test: /\.css$/,
// use:使用哪些loader进行处理,执行顺序是倒序依次执行,比如会先使用css-loader再使用style-loader
use: [
// style-loader会创建style标签,将js中的样式资源插入进行,添加到head中生效
'style-loader',
// css-loader会将css文件变成commonjs模块加载js中,里面内容是样式字符串
'css-loader'
]
},
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
// 将less文件编译成css文件,需要安装less和less-loader
'less-loader'
]
},
// 处理图片资源【webpack5会自动处理图片资源 !!加上以下配置反而图片显示不出来,webpack4可以用以下配置】
// {
// test: /\.(jpg|png|gif)$/,
// // 使用多个loader时可以用use:[],如果只使用一个loader可以直接写loader:‘xxx’
// // url-loader依赖file-loader,所以需要下载两个包
// loader: 'url-loader',
// // 图片配置信息
// options: {
// // 一般会对小图片进行base64处理,这里是当图片小于8kb时,就会被base64处理成字符串
// // 优点:减少请求数量(减轻服务器压力)
// // 缺点:图片体积会变大导致问价请求速度变慢
// limit: 10 * 1024, //根据项目情况来定,假如项目中小图片是9kb,难么这里可以设置10*1024
// // 在webpack4中ulr-loader默认使用es6模块化解析,而html-loader引入图片是commonjs
// // 解析时会出现问题:src内容会变为[object module]
// // 解决办法:关闭url-loader的es6模块化,使用commonjs解析
// esModule: false,
// // 打包后的图片的名称是hash值,字符比较长,可以自定义命名
// // 意思为:取hash值的前10位,[ext]是指取文件原来扩展名
// name: '[hash:10].[ext]'
// }
// },
// html-loader处理html中的img图片资源(负责引入img标签,然后交由url-loader进行解析处理)
{
test: /\.html$/,
loader: 'html-loader'
},
// 打包其他资源(除了html/css/js以外的资源)
{
// exclude:排除html,css,js资源的其他资源都适用file-loader(比如字体图标iconfont)
exclude: /\.(html|css|js)$/,
loader: 'file-loader'
}
]
},
// 插件(1.下载2.引入3.使用)
plugins: [
// html-webpack-plugin插件会打包html文件
// 功能:会默认创建一个空的html,自动引入打包后输出的所有资源(js/css)
new HtmlWebpackPlugin({
// template模版:意味复制./src/index.html文件,并自动引入打包后输出的所有资源
template: './src/index.html'
})
],
// 模式
mode: 'development'
}
常见的 loader plugin
1.loader
style-loader:用于将css编译完成的样式,挂载到页面style标签上
module.exports = {
module: {
rules: [
{
test: /\.css/,
use: ["style-loader"]
}
]
}
}
css-loader: 用于识别.css文件。
处理css必须配合style-loader共同使用,只安装css-loader样式不会生效。
module.exports = {
module: {
rules: [
{
test: /\.css/,
use: [
"style-loader",
"css-loader"
]
}
]
}
}
sass-loader: css预处理器。
module.exports = {
module: {
rules: [
{
test: /\.scss$/,
use: [
"style-loader",
"css-loader",
"sass-loader"
],
include: /src/,
},
]
}
}
babel-loader: 将Es6+ 语法转换为Es5语法。
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: {
loader: "babel-loader",
options: {
presets: [
['@babel/preset-env', { targets: "defaults"}]
]
}
}
},
]
}
}
eslint-loader: 用于检查代码是否符合规范,是否存在语法错误。
module.exports = {
module: {
rules: [
{
test: /\.ts$/,
use: ["eslint-loader", "ts-loader"],
enforce: "pre",
exclude: /node_modules/
},
{
test: /\.ts$/,
use: "ts-loader",
exclude: /node_modules/
}
]
}
}
2.plugin
html-webpack-plugin:自动生成一个index.html文件,将打包的js文件,自动通过script标签插入到body中
//插件安装
nmp install html-webpack-plugin --save-dev
//引入插件
const HtmlWebpackPlugin = require("html-webpack-plugin");
//在插件中配置
plugins:[
new HtmlWebpackPlugin({
//配置文件所在目录下面的插件
template: 'index.html'
})
]
uglifyjs-webpack-plugin:可以压缩js文件并且丑化js代码,使之可读性变差
// 安装
npm install uglifyjs-webpack-plugin@1.1.1 --save-dev
const UglifyjsWebpackPlugin = require("uglifyjs-webpack-plugin");
plugins:[
new UglifyjsWebpackPlugin()
]
webpack-dev-server:本地服务器
devserver:{
//服务哪个文件夹
contentBase:'./dist',
//是否需要实时监听
inline: true
}
//webpack.json
"script":{
"dev": "webpack-dev-server --open"
}
//然后使用 npm run dev就可以启动了
webpack-merge:在webpack.config.js里面内容太多的时候进行分割,分为prod(生产环境),dev(开发环境),base(基本),
然后在webpack.json中的“bulid”“dev”脚本后面增加 "–config ./build/prod.config.js"指定对应的webpackconfig。
//base.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry:"./src/main.js",
output: {
path:path.resolve(__dirname,'dist'),
filename: "bundle.js",
publicPath:"dist/"
},
module:{
rules:[
{
//正则表达式 匹配文件中的css文件
test:/\.css$/,
use:['style-loader','css-loader']
},
{
test: /\.less$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader" // compiles Less to CSS
}]
},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
//加载图片 小鱼limit时候就会使用base64转换
limit: 10000,
//取原来图片的name
name:'img/[name].[hash:8].[ext]'
}
}
]
},
{
//babel把es6转到es5
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
},
{
test:/\.vue$/,
use:['vue-loader']
}
]
},
resolve:{
//alias别名
alias:{
'vue$':'vue/dist/vue.esm.js'
},
extensions:['.js','.vue','.css']
},
plugins:[
new HtmlWebpackPlugin({
//配置文件所在目录下面的插件
template: 'index.html'
})
]
};
//prod.config.js
const UglifyjsWebpackPlugin = require("uglifyjs-webpack-plugin");
//引入插件
const WebpackMerge = require("webpack-merge");
const baseConfig = require("./base.config");
//合并webpack.config.js
module.exports = WebpackMerge(baseConfig,{
plugins:[
new UglifyjsWebpackPlugin()
]
});