# 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. 提交一个项目说明文档,要求思路流程清晰。 最终将录制的视频或说明文档和代码统一提交至作业仓库。