手写我的 VUE-CLI
栏目: JavaScript · 发布时间: 5年前
内容简介:webpack学习的大致过程在此记录一下。先创建一份 vue-cli 作为参考。然后创建 my-vue-cli 初始化项目结构,添加.gitignore等。
webpack学习的大致过程在此记录一下。
先创建一份 vue-cli 作为参考。 cli.vuejs.org/zh/guide/in…
$ yarn global add @vue/cli $ vue -V // 查看版本 $ vue init webpack vue-cli 复制代码
然后创建 my-vue-cli 初始化项目结构,添加.gitignore等。
$ npm init $ git init 复制代码
1. 初始化webpack
webpack.docschina.org/guides/inst…
// webpack 4.x+ $ yarn add webpack webapck-cli -D 复制代码
2. 添加项目结构
- 入口文件:src/main.js, 在main.js中随便写点js。
- html模版文件:index.html
- webpack配置文件: webpack.config.js
3. webpack 基础配置
// webpack.config.js const path = require('path') module.exports = { entry: { app: './src/main.js' }, output: { path: path.resolve(__dirname, './dist'), filename: '[name].[hash:8].js' } } 复制代码
// package.json { "scripts": { "build": "webpack", } } 复制代码
$ yarn build
, 会生成dist/app.**.js, 将app.**.js在浏览器 console 中运行试试。(webpack 命令会自动查找 webapck.config.js 并执行)。
4. 使用devServer, HtmlWebpackPlugin
$ yarn add webpack-dev-server -D $ yarn add html-webpack-plugin -D 复制代码
plugins: [ new HtmlWebpackPlugin({ template: path.resolve(__dirname, './index.html') }) ], devServer: { // https: true, open: true, host: '0.0.0.0', port: 8000, disableHostCheck: true, hot: true, proxy: {//配置跨域,访问的域名会被代理到本地的3000端口 '/api': 'http://localhost:3000' } } 复制代码
5. 转译ES6、ES7 使用 babel-loader
webpack.docschina.org/loaders/bab…
// 注意 babel-loader@7 与 babel-core@6 配套使用;babel-loader@8 与 babel-core@7 配套使用。
$ yarn add babel-loader babel-core babel-preset-env babel-preset-stage-2 -D $ yarn add babel-plugin-transform-runtime babel-runtime -D 复制代码
添加 .babelrc
文件
{ // presets 告诉 babel 源码使用了哪些新的语法特性。 "presets": [ [ "env", { "modules": false } ], "stage-2" ], // 生成的文件中,不产生注释, 会使 /* webpackChunkName: 'helloWorld' */ 失效 // "comments": false, "plugins": [ [ // babel-plugin-transform-runtime 减少冗余代码,依赖 babel-runtime "transform-runtime", { "helpers": true, "polyfill": true, "regenerator": true, "moduleName": "babel-runtime" } ] ], "env": { // 测试环境,test 是提前设置的环境变量,如果没有设置BABEL_ENV, 则使用NODE_ENV,如果都没有设置默认就是development "test": { "presets": [ "env", "stage-2" ], // instanbul是一个用来测试转码后代码的工具 "plugins": [ "istanbul" ] } } } 复制代码
// webpack.config.js module.exports = { module: { rules: [ { test: /\.(js|jsx)$/, exclude: /(node_modules|bower_components)/, loaders: [ { loader: 'babel-loader', options: { cacheDirectory: true, }, }, ], }, ] } } 复制代码
6. 接入less、postcss
$ yarn add less less-loader css-loader style-loader -D $ yarn add postcss-loader autoprefixer -D 复制代码
添加 .postcssrc
文件。
{ "plugins": { "autoprefixer": { "browsers": ["IOS>=7", "Android>=4.1", "IE>=9"], } } } 复制代码
7. 识别 .vue 文件
$ yarn add vue-loader vue-template-compiler -D $ yarn add vue 复制代码
resolve: { alias: { vue$: 'vue/dist/vue.runtime.esm.js' }, }, 复制代码
8. 对文件使用 url-loader(基于file-loader + limit功能)
$ yarn add url-loader -D
{ test: /\.(jpg|jpeg|gif|png|svg|webp)$/, use: [ { loader: 'url-loader', options: { limit: 8192, name: 'assets/images/[hash:8].[ext]', } } ] }, { test: /\.(woff|woff2|eot|ttf|otf)$/, use: [ { loader: 'url-loader', options: { name: 'assets/fonts/[hash:8].[ext]', } } ] }, 复制代码
9. 接入 vue-router
$ yarn add vue-router
// 添加别名 resolve: { alias: { "@": path.resolve(__dirname, 'src') }, }, // 按需加载, 注意.babelrc中: "comments": false,会使 /* webpackChunkName: 'helloWorld' */ 失效 const HelloWorld = () => import(/* webpackChunkName: 'helloWorld' */ '@/components/HelloWorld'); 复制代码
10. 使用 clean-webpack-plugin
const CleanWebpackPlugin = require('clean-webpack-plugin'); plugins: [ new CleanWebpackPlugin(), // 多版本共存模式时 必须要取消这个插件 ] 复制代码
11. 加入eslint + pritter + pre commit hook 约束代码提交
$ yarn add babel-eslint eslint eslint-config-standard eslint-plugin-html eslint-plugin-promise eslint-plugin-standard eslint-plugin-import eslint-plugin-node -D $ yarn add eslint-loader -D $ yarn add prettier -D --exact $ yarn add eslint-plugin-prettier eslint-config-prettier eslint-plugin-vue -D // lint-staged、 husky插件,这样再每次 commit 代码的时候都会格式化一下。 $ yarn add lint-staged husky@next -D 复制代码
// 添加 .eslintrc.js // 添加.prettierrc // package.json // pre-commit 约束代码提交 "husky": { "hooks": { "pre-commit": "lint-staged" } }, "lint-staged": { "*.{js,json,css,md,vue}": ["prettier --write", "git add"] } // webpack.config.js module: { rules: [ { test: /\.(js|vue)$/, loader: 'eslint-loader', enforce: 'pre', exclude: /(node_modules|bower_components)/, }, ] } 复制代码
12. 使用 CopyWebpackPlugin
// copy custom static assets new CopyWebpackPlugin([ { from: path.resolve(__dirname, './static'), to: 'static', ignore: ['.*'], }, ]), 复制代码
优化
1. 区分环境
不同环境,使用不同配置插件等。 $ yarn add cross-env -D
// package.json scripts: { "build": "cross-env NODE_ENV=production webpack", } // 使用 porcess.env.NODE_ENV 复制代码
2. 使用mode
webpack.docschina.org/concepts/mo… webpack4+ mode简化了许多配置。
const mode = process.env.NODE_ENV || 'development' module.exports = { mode: mode, } 复制代码
3. 输出文件版本控制
开发环境的 --hot 不能使用contenthash、chunkhash
const chunkhash = isDev ? '[name].[hash:8].js' : '[name].[chunkhash:8].js' const contenthash = isDev ? '[name].[hash:8].css' : '[name].[contenthash:8].css' output: { path: path.resolve(__dirname, './dist'), filename: chunkhash, chunkFilename: chunkhash, publicPath: '/', }, 复制代码
4. 生产环境抽离每一个 chunk 的 css 使用 MiniCssExtractPlugin
module: { rules: [ { test: /\.(css|less)$/, use: { loader: isDev ? 'style-loader' : MiniCssExtractPlugin.loader }, } ] } plugins: [ new MiniCssExtractPlugin({ filename: contenthash, chunkFilename: contenthash, }), ] 复制代码
5. 分离第三方插件,持久化缓存
webpack.docschina.org/configurati… $ yarn add uglifyjs-webpack-plugin
optimization: { runtimeChunk: { name: 'manifest', }, splitChunks: { cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, chunks: 'all', name: 'vendor', }, }, }, minimizer: [ new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: true, }), new OptimizeCSSAssetsPlugin(), ], }, 复制代码
6. 使用可视化分析 BundleAnalyzerPlugin
// package.json scripts: { "analyz": "NODE_ENV=production npm_config_report=true npm run build" } // webpack.config.json plugins: [ ...(process.env.npm_config_report ? [new BundleAnalyzerPlugin()] : []), ] 复制代码
3. 优化构建速度
1. 缩小文件搜素范围
2. 生成动态链接库 使用DllPlugin(将第三方插件只编译一次)
3. 利用 CUP 多核, 使用 HappyPack 加快 loader 转换
webpack 构建流程中最耗时的就是 Loader 转换,js 单线程只能对文件一个一个的处理,HappyPack 原理就是将这部分任务,分解到多个进程,减少构建时间。
大中型项目中,使用 happypack 才能看到比较明显的构建速度提升。
// 见 git 记录"使用happypack" 复制代码
4. 利用 CUP 多核, 使用 ParalleUglifyPlugin 加快 UglifyJS 的压缩。
new ParallelUglifyPlugin({ uglifyJS: { output: { // 最紧凑输出 beautify: false, // 删除所有注释 comments: false, }, compress: { drop_console: !isDev, collapse_vars: true, reduce_vars: true, }, }, }), 复制代码
4. 编写 Loader
webpack.docschina.org/contribute/…
// webpack.config.js module.exports = { module: { rules: [ { test: /\.vue$/, exclude: /(node_modules|bower_components)/, use: [ { loader: 'vue-loader', options: { loaders: { // happy 不支持 vue-loader, 将js 交由 happypack js: 'happypack/loader?id=babel', }, }, }, { // 为每个 vue 文件 添加 ~@/assets/less/variable.less, 避免人工每次导入。 loader: 'less-auto-import-loader', options: { url: '~@/assets/less/variable.less', }, }, ], }, ] } resolveLoader: { // 增加 loader 的查找范围 modules: ['node_modules', './loaders/'], }, } 复制代码
5. 编写 Plugin
***重点是***找到合适的事件点去完成功能。compiler 钩子
// EndWebpackPlugin webpack构建成功或失败后执行回调 class EndWebpackPlugin { constructor(doneCallback, failCallback) { this.doneCallback = doneCallback this.failCallback = failCallback } apply(compiler) { compiler.plugin('done', (stats) => { this.doneCallback(stats) }) compiler.plugin('failed', (err) => { this.doneCallback(err) }) } } // webpack.config.js const EndWebpackPlugin = require('end-webpack-plugin'); plugins: [ new EndWebpackPlugin((stats) => {}, (err) => {}) ] 复制代码
github: github.com/lizhuang93/…
webpack官网: webpack.docschina.org/concepts/
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Java程序设计
宋中山 严千钧 等编 / 清华大学出版社 / 2005-8 / 27.00元
本书全面、系统地介绍了Java语言的基本概念、基本语法和编程方法。主要内容包括:Java语言概述、数据类型与运算符、流程控制语句、类与对象、继承与多态、异常处理、工具类和算法、Applet小应用程序、图形用户界面、输入和输出、Java多线程以及Java高级编程。每章后面附有习题,读者可参考使用。 本书内容丰富,结构合理,语言简洁,深入浅出,通俗易懂。基础知识与程序实例相结合,示例典型......一起来看看 《Java程序设计》 这本书的介绍吧!