面试题记系列之Webpack篇
分类:javascript
前言
本篇幅用于练习用 webpack4 搭建 vue 开发环境,主要从以下几点入手
- webpack 的安装
- 跟着官网文档搭建一个 webpack 管理的项目,了解几个重要概念:入口、输出、loader、plugin
- 安装 vue、vue-router、vuex、element-ui 等
- 着手性能优化,提升打包构建速度,减小输体积等
- 本文收录在GitHub有什么问题欢迎 Issues
安装/起步
安装 webpack
// 初始化 yarn
yarn init -y
// 本地安装 webpack
yarn add webpack --dev
// 安装webpack脚手架
yarn add webpack webpack-cli --dev
创建配置文件
- 目录
webpack-demo
|- /src
|- main.js
|- App.vue
|- package.json
+ |- webpack.config.js
|- index.html
- webpack.config.js
const path = require("path");
module.exports = {
entry: {
app: "./src/main.js",
},
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist"),
},
};
- index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
- main.js
import Vue from "vue";
import App from "./App";
const vm = new Vue({
el: "#app",
render: (h) => h(App),
});
- App.vue
<template>
<div id="app">
<router-view> </router-view>
</div>
</template>
<script>
export default {
name: "App",
};
</script>
管理资源(配置 loader)
style-loader css-loader
// 安装
yarn add style-loader css-loader -dev
// 在 webpack.config.js 文件中添加
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
],
}
// 然后在 main.js 中就可以引入 css 文件了
import "./style.css";
vue-loader
// 安装vue
yarn add vue
yarn add vue-loader css-loader vue-template-compiler --dev
// 在 webpack.config.js 文件中添加
module: {
rules: [
{
test: /\.vue$/,
use: ["vue-loader"],
},
{
test: /\.css$/,
use: ["vue-style-loader", "css-loader"],
},
];
}
babel-loader
// 安装
yarn add babel-loader @babel/core @babel/preset-env --dev
// 在 webpack.config.js 文件中添加
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
},
},
},
];
}
// 在根目录下创建 .babelrc 文件
{
"presets": [
["@babel/preset-env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}]
]
}
安装 vue-router
// 安装
yarn add vue-router
// 新建router/index文件
import Vue from "vue";
import Router from "vue-router";
Vue.use(Router);
// 相关配置可以参考
// https://github.com/PanJiaChen/vue-element-admin/tree/master/src/router
安装 vuex
// 安装
yarn add vuex
// 新建store/index文件
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
// 相关配置可以参考
// https://github.com/PanJiaChen/vue-element-admin/tree/master/src/store
管理输出
配置输出
// [name] 据入口起点定义的名称,动态地产生 bundle 名称
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist"),
}
添加 HtmlWebpackPlugin 生成一个内存 html 并把打包好的 js 文件路径追加到 html 页面中
// 安装
yarn add html-webpack-plugin --dev
// 在webpack.config.js 中引入
const HtmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
new HtmlWebpackPlugin({
title: '管理输出'
})
]
清理 /dist 文件夹 clean-webpack-plugin
// 安装
yarn add clean-webpack-plugin --dev
// 在webpack.config.js 中引入
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
plugins: [
new CleanWebpackPlugin(),
]
配置开发环境
使用 source map
当 webpack 打包源代码时,可能会很难追踪到 error(错误) 和 warning(警告) 在源代码中的原始位置。
// 在webpack.config.js 中引入
devtool: "inline-source-map",
使用 webpack-dev-server
热更新 实时重新加载
// 安装
yarn add webpack-dev-server --dev
// 在 webpack.config.js 中引入
devServer: {
contentBase: './dist',
},
// 在 package.json 中添加
"scripts": {
"start": "webpack server --open"
},
配置热模块替换
// 在 webpack.config.js 中添加
const webpack = require('webpack');
devServer: {
contentBase: './dist',
hot: true
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
tree shaking
移除 JavaScript 上下文中的未引用代码(dead-code)
// 将文件标记为 side-effect-free(无副作用)
// 在 package.json 中添加
{
"sideEffects": false
}
- 压缩输出结果
通过 import 和 export 语法,我们已经找出需要删除的“未引用代码(dead code)”,然而,不仅仅是要找出,还要在 bundle 中删除它们。
配置生产环境
安装 merge
yarn add webpack-merge --dev
为每个环境编写彼此独立的 webpack 配置
// 调整webpack配置文件
- webpack.config.js
+ webpack.common.js;
+ webpack.dev.js;
+ webpack.prod.js;
// 在 .dev 和 .prod 文件中引入
const { merge } = require("webpack-merge");
module.exports = merge(common, {
mode: "development/production",
...配置信息
}
更改 package.json
"scripts": {
"start": "webpack server --open --config webpack.dev.js",
"build": "webpack --config webpack.prod.js"
},
代码分离
// webpack.common.js 中添加
optimization: {
// 插件可以将公共的依赖模块提取到已有的 entry chunk 中,或者提取到一个新生成的 chunk, 提取公共资源
splitChunks: {
chunks: "all";
}
}
面试该怎么回答参考
当面试官问 Webpack 的时候他想知道什么
「吐血整理」再来一打 Webpack 面试题