# fed-e-task-02-02
**Repository Path**: learning-summary/fed-e-task-02-02
## Basic Information
- **Project Name**: fed-e-task-02-02
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2020-12-13
- **Last Updated**: 2020-12-20
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 一、简答题
## 1、Webpack 的构建流程主要有哪些环节?如果可以请尽可能详尽的描述 Webpack 打包的整个过程。
主要环节
- 安装webpack ,yarn add webpack@4.44.2 webpack-cli@3.3.3 -D
- 配置webpack.config.js文件
- 在webpack.config.js中配置entry, output以及mode
- 根据要加载的文件类型,安装配置不同的loader加载器
- 根据项目的需求,实现非loader的功能,安装相应的plugins
- 配置devserver 开启自动化编译和浏览器预览
- 配置optimization 进行项目优化等等操作。
## 2、Loader 和 Plugin 有哪些不同?请描述一下开发 Loader 和 Plugin 的思路。
Loader与Plugin的区别:
webpack只能识别javascript和json文件,而loader能够让webpack去处理更多类型的文件,让他们转换成有效的模块,形成依赖树。
Plugin插件就是处理除了loader转换模块之外的任务,比如打包优化、资源管理
**Loader实现思路:**
- module.exports导出一个function接收形参source
- 处理source文件
- 返回一个js字符串
**Plugins实现思路:**
- 导出一个插件类,在类的原型上定义apply方法
- webpack初始化完成,apply方法上接收compiler对象
- 通过compiler对象的钩子,定义在某个阶段注入插件,通过tabable定义钩子的触发方式
- tabable中的方法接受插件名和一个函数,这个函数中接受compliation对象
- 通过compliation对象上的属性,执行自己想要实现的功能,比如资源类的assets
- 最后将处理后的结果给compliation上assets属性重新赋值
# 二、编程题
## 1、使用 Webpack 实现 Vue 项目打包任务 具体任务及说明:
**说明:**
1. **安装和配置eslint**
- 删除package中的eslint相关的配置.
- yarn add eslint ,然后运行eslint --init 初始化 .eslintrc.js ,根据提示安装响应的包
```js
yarn add eslint-plugin-vue@latest eslint-config-standard@latest eslint@^7.12.1 eslint-plugin-import@^2.22.1 eslint-plugin-node@^11.1.0 eslint-plugin-promise@^4.2.1 -D
```
2. **安装和配置prettier**
- 安装
```js
yarn add prettier @vue/eslint-config-prettier eslint-plugin-prettier -D
```
- 在.eslintrc.js中添加
```js
module.exports = {
extends: [
...
'@vue/prettier'
],
}
```
- 新建.prettierrc.js文件
```js
// prettier.config.js or .prettierrc.js
module.exports = {
trailingComma: "es5",
tabWidth: 4,
semi: false,
singleQuote: true
};
```
3. **安装和配置lint-stage和husky**
- 安装
```js
yarn add lint-staged husky -D
```
- 在package.json中添加
```json
{
"scripts": {
"lint-staged:js": "eslint --ext .js,.vue,.ts",
"lint:fix": "eslint --fix --cache --ext .js,.vue,.ts --format=pretty ./src",
"lint:js": "eslint --cache --ext .js,.vue,.ts,--format=pretty ./src",
"lint:prettier": "prettier --check \"src/**/*\" --end-of-line auto",
"precommit": "lint-staged",
},
"lint-staged": {
"**/*.{js,vue,ts,less,md,json}": [
"prettier --write",
"npm run lint:js",
"git add"
]
},
}
```
4. **安装webpack**
```js
yarn add webpack@4.44.2 webpack-cli@3.3.3 -D
```
5. **安装webpack-merge,配置多环境**
```js
yarn add webpack-merge -D
```
webpack.common.js中
```js
module.exports = {
entry: "./src/main.js",
output: {},
};
```
webpack.dev.js中
```js
const common = require("./webpack.common");
const { merge } = require("webpack-merge");
module.exports = merge(common, {
mode: "development",
});
});
```
webpack.prod.js中
```js
const common = require("./webpack.common");
const { merge } = require("webpack-merge");
module.exports = merge(common, {
mode: "production",
});
});
```
6. **在webpack.common.js中配置打包入口和输出**
```js
const path = require("path");
module.exports = {
entry: "./src/main.js",
output: {
filenaem: "[name].[contenthash].js",
path: path.resolve(__dirname, "dist"),
},
};
};
```
7. **在package.json中配置build命令**
```json
{
"scripts": {
"build": "webpack --config webpack.prod.js",
},
}
```
运行 yarn build命令 之后提示如下,
8. **解析.vue结尾的文件**
- 安装
```js
yarn add vue-loader vue-template-compiler -D
```
- 在webpack.common.js中
```js
const VueLoaderPlugin = require("vue-loader/lib/plugin");
module.exports = {
module: {
rules: [
{
test: /\.vue$/,
use: ["vue-loader"],
},
],
},
plugins: [new VueLoaderPlugin()],
}
```
9. 解析.css文件和.less文件
- 安装
```js
yarn add css-loader style-loader -D
```
- webpack.common.js中
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.less$/,
use: ["style-loader", "css-loader", "less-loader"],
},
],
},
}
```
10. **解析图片资源文件**
- 安装
```js
yarn add url-loader file-loader -D
```
- webpack.common.js中
```js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpe?g|gif|webp)(\?.*)?$/i,
use: [
{
loader: "url-loader",
options: {
limit: 4096,
fallback: "file-loader",
esModule: false,
},
},
],
},
],
},
};
```
11. **解析.js文件**
- 安装
```js
yarn add babel-loader @babel/core @babel/preset-env @vue/cli-plugin-babel eslint-loader -D
```
- webpack.common.js中
```js
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
},
},
'eslint-loader',
],
},
],
},
}
```
12. **CleanWebpackPlugin、ProgressPlugin、HtmlWebpckPlugin**
CleanWebpackPlugin每次构建前清除目标目录
HtmlWebpckPlugin根据index.html模板生成html文件
ProgressPlugin显示webpack构建的进度
- 安装
```js
yarn add clean-webpack-plugin html-webpack-plugin -D
```
- webpack.prod.js中
```js
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const webpack = require('webpack')
module.exports = merge(common, {
mode: 'production',
plugins: [
new webpack.ProgressPlugin(),
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'vue-app-base',
template: 'public/index.html',
}),
],
})
}
```
执行yarn build 出现BASE_URl is not defined
这个错误出现的原因是因为public下面的index.html存在一个全局变量的BASE_URL这个时候需要用DefinePlugin定义全局变量
webpack.prod.js中添加如下
```js
module.exports = merge(common, {
plugins: [
new webpack.DefinePlugin({
BASE_URL: JSON.stringify('/'),
}),
.....
],
})
```
13. **复制public中文件到dist目录中**
- 安装
```js
yarn add copy-plugin-webpack@5.1.2 -D
```
- webpack.prod.js中
```js
const path = require('path')
const CopyPlugin = require('copy-webpack-plugin')
module.exports = {
plugins: [
new CopyPlugin([
{
from: path.join(__dirname, 'public'),
to: path.join(__dirname, 'dist'),
ignore: [
'.DS_Store',
{
glob: 'index.html',
matchBase: false,
},
],
},
]),
]
}
```
14. **开启server并自动编译**
- 安装
```js
yarn add webpack-dev-server -D
```
- webpack.dev.js中
```js
module.exports = {
devServer: {
contentBase: path.join(__dirname, 'public'),
compress: true,
open: true,
port: 9000,
},
}
```
- package.json中配置
```json
{
"scripts": {
"serve": "webpack-dev-server --config webpack.dev.js --watch",
},
}
```
15. **配置打包优化**
- 安装
```js
yarn add terser-webpack-plugin -D
```
- webpack.prod.js中
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserWebpackPlugin({
cache: true,
parallel: true,
sourceMap: true,
}),
],
splitChunks: {
chunks: 'all',
minChunks: 1,
cacheGroups: {
vendors: {
name: 'chunk-vendors',
test: /[\\/]node_modules[\\/]/,
priority: -10,
chunks: 'all',
},
common: {
name: 'chunk-common',
minChunks: 2,
chunks: 'initial',
priority: -20,
},
},
},
runtimeChunk: {
name: (entrypoint) => `runtimechunk~${entrypoint.name}`,
},
},
}
```
16. 最后调整开发和生产的配置,如下
webpack.common.js
```js
const path = require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './src/main.js',
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
},
},
'eslint-loader',
],
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader'],
},
{
test: /\.vue$/,
use: ['vue-loader'],
},
{
test: /\.(png|jpe?g|gif|webp)(\?.*)?$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 4 * 1024,
fallback: 'file-loader',
esModule: false,
},
},
],
},
],
},
plugins: [
new VueLoaderPlugin(),
new webpack.DefinePlugin({
BASE_URL: JSON.stringify('/'),
}),
new webpack.ProgressPlugin(),
new HtmlWebpackPlugin({
title: 'vue-app-base',
template: 'public/index.html',
}),
],
}
```
webpack.dev.js
```js
const path = require('path')
const common = require('./webpack.common')
const { merge } = require('webpack-merge')
module.exports = merge(common, {
mode: 'development',
devtool: 'cheap-module-eval-source-map',
devServer: {
contentBase: path.join(__dirname, 'public'),
compress: true,
open: true,
port: 9000,
},
})
```
webpack.prod.js
```js
```
先下载任务的基础代码 百度网盘链接: https://pan.baidu.com/s/1pJl4k5KgyhD2xo8FZIms8Q 提取码: zrdd
这是一个使用 Vue CLI 创建出来的 Vue 项目基础结构
有所不同的是这里我移除掉了 vue-cli-service(包含 webpack 等工具的黑盒工具)
这里的要求就是直接使用 webpack 以及你所了解的周边工具、Loader、Plugin 还原这个项目的打包任务
尽可能的使用上所有你了解到的功能和特性
作业要求
本次作业中的编程题要求大家完成相应代码后(二选一)
1. 简单录制一个小视频介绍一下实现思路,并演示一下相关功能。
2. 提交一个项目说明文档,要求思路流程清晰。
最终将录制的视频或说明文档和代码统一提交至作业仓库。