热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:Webpack5搭建Vue3+TS项目

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Webpack5搭建Vue3+TS项目相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Webpack5 搭建 Vue3 + TS 项目相关的知识,希望对你有一定的参考价值。







点击关注下方卡片关注我????????


回复“Vue3”查阅 Vue3精选文章


各位小伙伴,我回广州了,今天开始更新了。


作者:Corwien


来源:SegmentFault 思否社区


1. 前言


笔者两年前曾写过一篇文章《Webpack4 搭建 Vue 项目》,后来随着 webpack5 和 vue3 的面世,一直想升级下我这个 createVue 项目,但是苦于没有时间(其实是因为懒),一直拖延至今。捣鼓了好几天,终于搭建好整个项目,因此仅以此文记录升级搭建的过程。


PS: 其实也可以用官方脚手架搭建的,为何要自己从头做起呢?有脚手架我不用,我就折腾。哎,就是玩儿~????


2. 准备工作


为何升级?除了折腾外,便是享受新版本带给我们的新特性体验。


Webpack5 的新特性


  • 持久化缓存

  • moduleIds & chunkIds 的优化

  • 更智能的 tree shaking

  • Module Federation

  • ...


Vue3 的新特性


  • 更小

  • 更快

  • 加强 TypeScript 支持

  • 加强 API 设计一致性

  • 提高自身可维护性

  • 开放更多底层功能


确定项目技术栈


  • 编程语言:TypeScript 4.2.4

  • 构建工具:[Webpack 5.33.2]()

  • 前端框架:Vue 3.0.11

  • 路由工具:Vue Router 4.0.6

  • 状态管理:Vuex 4.0.0

  • CSS 预编译:Sass / Less

  • HTTP 工具:Axios

  • Git Hook 工具:Husky + Lint-staged

  • 代码规范:EditorConfig + Prettier + ESLint

  • 提交规范:Commitlint

  • 构建部署:Travis


3. 项目搭建


此文并不是从零搭建,而是在 createVue@v1.0.0 的基础上修改搭建,如若看不懂,可以先看《Webpack4 搭建 Vue 项目》,跟着一步步搭建,后再看此文升级


创建 createVue 文件夹,进入该文件夹, npm init 初始化项目


老规矩,安装 webpack 四件套npm i webpack webpack-cli webpack-dev-server webpack-merge --save-dev


当前使用版本:
"webpack": "^5.33.2",
"webpack-bundle-analyzer": "^4.4.1",
"webpack-cli": "^4.6.0",
"webpack-dev-server": "^3.11.2",
"webpack-merge": "^5.7.3",

webpack5 启动开发服务器命令与之前有所变化,从 webpack-dev-server 转变为 webpack serve, 因此 package.json 中 script 的 start 修改为: "start": "webpack serve --progress --hot --inline --config build/webpack.dev.js"


  1. 创建相应文件


与之前没有太大差异。增加变动的有一下几点:


1). 持久化缓存,增加 cache 配置. v5 中缓存默认是 memory,修改设置"filesystem"写入硬盘


// webpack.dev.js
module.exports = merge(common, {
  cache: {
    type: 'filesystem',
  }
  //...
}

2). 去除插件 clean-webpack-plugin(v5支持),webpack.HashedModuleIdsPlugin(v5更好的 moduleIds & chunkIds),HardSourceWebpackPlugin(v5支持),happypack(v5不兼容)


安装 vue 核心解析插件


解析插件有所不同,从 vue-template-compiler 变成了 @vue/compiler-sfcvue-loader 保持不变。 npm i vue-loader @vue/compiler-sfc --save-dev


// 当前我使用版本
"vue-loader": "^16.2.0",
"@vue/compiler-sfc": "^3.0.11",

安装 vue3 及相关库,添加 vue 类型文件


npm i vue@next vuex@4.0.0-rc.1 vue-router --save


src 文件夹下添加 shims-vue.d.ts 文件,解决 vue 类型报错


// shims-vue.d.ts
declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  const component: DefineComponent<{}, {}, any>
  export default component
}

安装 html 模板解析插件


npm i html-webpack-plugin --save-dev


安装 typescript 及解析插件


npm i typescript ts-loader --save-dev


配置ts-loader解析&#xff1a;


// webpack.base.js
// rules
{
    test: /\\.(t|j)s$/,
    exclude: /node_modules/,
    use: [
      {
        loader: &#39;ts-loader&#39;,
        options: {
          // 指定特定的ts编译配置&#xff0c;为了区分脚本的ts配置
          configFile: path.resolve(__dirname, &#39;../tsconfig.loader.json&#39;),
          // 对应文件添加个.ts或.tsx后缀
          appendTsSuffixTo: [/\\.vue$/],
        },
      },
    ],
}

ts-loader 为单进程执行类型检查和转译&#xff0c;因此效率有些慢&#xff0c;可以用多进程方案&#xff1a;即关闭ts-loader的类型检查&#xff0c;类型检查由 fork-ts-checker-webpack-plugin 插件执行。npm i fork-ts-checker-webpack-plugin --save-dev


// webpack.base.js
// rules
{
    test: /\\.(t|j)s$/,
    exclude: /node_modules/,
    use: [
      {
        loader: &#39;ts-loader&#39;,
        options: {
          // 指定特定的ts编译配置&#xff0c;为了区分脚本的ts配置
          configFile: path.resolve(__dirname, &#39;../tsconfig.loader.json&#39;),
          // 对应文件添加个.ts或.tsx后缀
          appendTsSuffixTo: [/\\.vue$/],
          transpileOnly: true, // ? 关闭类型检查&#xff0c;即只进行转译
        },
      },
    ],
}
// plugins push
new ForkTsCheckerWebpackPlugin()

至此项目基本可以跑起来了&#xff0c;那么有个问题了&#xff1a;Ts 可以编译为指定版本的 js&#xff0c;那么还需要 babel 么&#xff1f;


tsc 的 target 只转译语法&#xff0c;不集成 polyfill&#xff0c;所以还是得要 babel。


比如把箭头函数转成普通 function、aysnc &#43; await 变成 Promise.then&#xff0c;这是语法转译&#xff1b;


但你运行环境里如果没有 Promise.prototype.finally&#xff0c;那没有就还是没有。


因此我们项目里还是需要 babel.


Webpack 转译 Typescript 现有方案:



综合考虑性能和扩展性&#xff0c;目前比较推荐的是 babel&#43;fork-ts-checker-webpack-plugin 方案。


在 babel7 之前&#xff0c;是需要同时使用 ts-loader 和 babel-loader 的&#xff0c;其编译过程 TS > TS 编译器 > JS > Babel > JS 。可见编译了两次js&#xff0c;效率有些低下。但是 babel7 出来之后有了解析 typescript 的能力&#xff0c;有了这一层面的支持&#xff0c;我们就可以只使用 babel&#xff0c;而不用再加一轮 ts 的编译流程了。


在 babel 7 中&#xff0c;我们使用新的 &#64;babel/preset-typescript 预设&#xff0c;结合一些插件便可以解析大部分的 ts 语法。


那么&#xff0c;Babel 是如何处理 TypeScript 代码的呢&#xff1f;


Babel 删除了所有 TypeScript&#xff0c;将其转换为常规的 Javascript&#xff0c;并继续以它自己的方式处理。删除了 typescript 则不需要进行类型检查&#xff0c;不会有烦人的类型错误提醒&#xff0c;因此编译速度提升&#xff0c;开开心心编程????


当然&#xff0c;类型安全性检查必不可少&#xff0c;我们可以统一在某个时间集中处理&#xff0c;增加 script&#xff1a;


"check-types": "tsc --watch",

添加 babel 解析 typescript


# 安装以下依赖 --save-dev
# webpack loader
babel-loader
# babel 核心
&#64;babel/core
# 智能转换成目标运行环境代码
&#64;babel/preset-env
# 解析 typescript 的 babel 预设
&#64;babel/preset-typescript
# polyfill 
&#64;babel/plugin-transform-runtime
# 支持 ts 类的写法
&#64;babel/plugin-proposal-class-properties 
# 支持三点展开符
&#64;babel/plugin-proposal-object-rest-spread
# 安装以下依赖 --save
&#64;babel/runtime
&#64;babel/runtime-corejs3
"core-js": "^3.11.0",

删除 ts-loader, 添加 babel-loader


{
    test: /\\.(t|j)s$/,
    exclude: /node_modules/,
    use: [
      {
        loader: &#39;babel-loader&#39;,
      },
    ],
}

项目根目录添加 babel 配置文件 babel.config.js


module.exports &#61; {
  presets: [
    [
      &#39;&#64;babel/preset-env&#39;,
      {
        useBuiltIns: &#39;usage&#39;, // 按需引入 polyfill
        corejs: 3,
      },
    ],
    [
      &#39;&#64;babel/preset-typescript&#39;, // 引用Typescript插件
      {
        allExtensions: true, // 支持所有文件扩展名&#xff0c;否则在vue文件中使用ts会报错
      },
    ],
  ],
  plugins: [
    [
      &#39;&#64;babel/plugin-transform-runtime&#39;,
      {
        corejs: 3,
      },
    ],
    &#39;&#64;babel/proposal-class-properties&#39;,
    &#39;&#64;babel/proposal-object-rest-spread&#39;,
  ],
}

4. 代码规范


项目中代码规范集成了 EditorConfig&#xff0c; Prettier&#xff0c; ESLint&#xff0c; Husky&#xff0c; Lint-staged&#xff0c;以及如何解决 Prettier 和 ESLint 的冲突的问题&#xff0c;具体实现可以参考 《从 0 开始手把手带你搭建一套规范的 Vue3.x 项目工程环境》这篇文章&#xff0c;讲的很详细这里不再赘述。


5. 提交规范


利用 inquirer 选择配置好的提交类型&#xff0c;以及配合 commitlint 实现 commit 检查


npm i inquirer shelljs &#64;commitlint/{cli,config-conventional} -D

添加 package.json 的 script &#xff1a;


"commitlint": "commitlint -e", 
"commit": "node commit/git-commit.js"

创建 commit/git-commit.js 文件


const shell &#61; require(&#39;shelljs&#39;)
const inquirer &#61; require(&#39;inquirer&#39;)
const prompsConfig &#61; {
  ciType: [
    {
      type: &#39;list&#39;,
      name: &#39;type&#39;,
      message: &#39;请选择本次提交的类型:&#39;,
      choices: [
        {
          name: &#39;引入新特性&#39;,
          value: &#39;feat&#39;,
        },
        {
          name: &#39;改进代码的结构格式/样式&#39;,
          value: &#39;style&#39;,
        },
        {
          name: &#39;修复 bug&#39;,
          value: &#39;fix&#39;,
        },
        {
          name: &#39;提升性能&#39;,
          value: &#39;perf&#39;,
        },
        {
          name: &#39;删除代码或文件&#39;,
          value: &#39;delete&#39;,
        },
        {
          name: &#39;其他修改, 比如改变构建流程、或者增加依赖库、工具等&#39;,
          value: &#39;chore&#39;,
        },
        {
          name: &#39;重构&#39;,
          value: &#39;refactor&#39;,
        },
        {
          name: &#39;撰写文档&#39;,
          value: &#39;docs&#39;,
        },
        {
          name: &#39;增加测试&#39;,
          value: &#39;test&#39;,
        },
        {
          name: &#39;更新打包文件&#39;,
          value: &#39;build&#39;,
        },
        {
          name: &#39;初次提交&#39;,
          value: &#39;init&#39;,
        },
        {
          name: &#39;发布/版本标签&#39;,
          value: &#39;release&#39;,
        },
        {
          name: &#39;部署功能&#39;,
          value: &#39;deploy&#39;,
        },
        {
          name: &#39;代码回滚&#39;,
          value: &#39;revert&#39;,
        },
        {
          name: &#39;CI持续集成修改&#39;,
          value: &#39;ci&#39;,
        },
      ],
    },
  ],
  ciMsg: {
    type: &#39;input&#39;,
    name: &#39;msg&#39;,
    message: &#39;请输入提交文本:&#39;,
    validate: function (value) {
      if (value) {
        return true
      }
      return &#39;文本必须输入!&#39;
    },
  },
}
async function gitCommit() {
  let { type } &#61; await inquirer.prompt(prompsConfig.ciType)
  let { msg } &#61; await inquirer.prompt(prompsConfig.ciMsg)
  shell.exec(&#96;git commit -m "${type}: ${msg}"&#96;, function () {
    console.log(&#96;\\n提交脚本: git commit -m "${type}: ${msg}"&#96;)
  })
}
gitCommit()

配置 commitlint 类型&#xff0c;创建 commitlint.config.js 文件&#xff1a;


module.exports &#61; {
  extends: [&#39;&#64;commitlint/config-conventional&#39;],
  rules: {
    &#39;type-enum&#39;: [2, &#39;always&#39;, [
      &#39;build&#39;, &#39;chore&#39;, &#39;ci&#39;, &#39;feat&#39;, &#39;docs&#39;, &#39;fix&#39;, &#39;perf&#39;, &#39;revert&#39;, &#39;refactor&#39;, &#39;style&#39;, &#39;test&#39;, &#39;init&#39;, &#39;build&#39;, &#39;release&#39;, &#39;delete&#39;
     ]],
  }
};

完成上述操作后&#xff0c;git add 相关文件&#xff0c;执行 npm run commit 即可执行 commit 校验


6. 构建部署 Travis CI


Travis CI 是一款构建和测试的自动化工具&#xff0c;不仅可以提高效率&#xff0c;还能使开发流程更可靠和专业化&#xff0c;从而提高软件的价值。而且&#xff0c;它对于开源项目是免费的&#xff0c;不花一分钱&#xff0c;就能帮你做掉很多事情。详细介绍可以查看 阮一峰——《持续集成服务 Travis CI 教程》


首先&#xff0c;访问官方网站 travis-ci.org&#xff0c;点击右上角的个人头像&#xff0c;使用 Github 账户登入 Travis CI。


找到对应的仓库&#xff0c;打开开关添加仓库



在 github 上 setting/Developer settings/Personal access token 处生成 travis token



点击对应仓库的 setting



设置环境变量 GITHUB_TOKEN 为刚才 github 处生成的 token



创建 .travis.yml 配置文件&#xff1a;


language: node_js
node_js:
  - 12
branchs:
  only:
    - master
cache:
  directories:
    - node_modules
install:
  - yarn install
scripts:
  - yarn build
deploy:
  provider: pages
  local_dir: dist
  skip_cleanup: true
  # 在 GitHub 上生成的令牌&#xff0c;允许 Travis 推送代码到你的仓库。
  # 在仓库对应的 Travis 设置页面中配置&#xff0c;用于安全控制。
  github_token: $GITHUB_TOKEN
  keep_history: true
  on:
    branch: master

这样&#xff0c;当你 push 到 master 或者 pr 合并到 master 的时候&#xff0c;就会触发部署脚本的执行&#xff0c;将生成的 dist 推送至 gh-pages 分支



7. 存在问题及总结


  • 构建时间比 webpack4 长&#xff0c;可能是由于 ts 的引入&#xff0c;以及 happypack 多进程构建的移除造成时间略长

  • dev server 不会自增 port

  • fork-ts-checker-webpack-plugin 无法检测 vue 中的 ts 类型错误


捣鼓了挺长一段时间&#xff0c;也了解了蛮多工程化的东西&#xff0c;虽然不一定能用于实际项目中&#xff0c;但还是算有所收获吧&#xff01;


END



推荐阅读  点击标题可跳转


5个常问的 Vue3 优势点


不要再用 Vue2 的思维写 Vue3 了


比较JS合并数组的各种方法及其优劣


觉得本文对你有帮助&#xff1f;请分享给更多人


关注下方「前端开发博客」&#xff0c;提升前端技能



如果觉得这篇文章还不错&#xff0c;来个【分享、点赞、在看】三连吧&#xff0c;让更多的人也看到~



   “分享、点赞、在看” 支持一波  





推荐阅读
  • 深入解析Redis内存对象模型
    本文详细介绍了Redis内存对象模型的关键知识点,包括内存统计、内存分配、数据存储细节及优化策略。通过实际案例和专业分析,帮助读者全面理解Redis内存管理机制。 ... [详细]
  • 异常要理解Java异常处理是如何工作的,需要掌握一下三种异常类型:检查性异常:最具代表性的检查性异常是用户错误或问题引起的异常ÿ ... [详细]
  • 2018-2019学年第六周《Java数据结构与算法》学习总结
    本文总结了2018-2019学年第六周在《Java数据结构与算法》课程中的学习内容,重点介绍了非线性数据结构——树的相关知识及其应用。 ... [详细]
  • 尽管深度学习带来了广泛的应用前景,其训练通常需要强大的计算资源。然而,并非所有开发者都能负担得起高性能服务器或专用硬件。本文探讨了如何在有限的硬件条件下(如ARM CPU)高效运行深度神经网络,特别是通过选择合适的工具和框架来加速模型推理。 ... [详细]
  • 如何使用PyCharm及常用配置详解
    对于一枚pycharm工具的使用新手,正确了解这门工具的配置及其使用,在使用过程中遇到的很多问题也可以迎刃而解,文中有非常详细的介绍, ... [详细]
  • 本文详细介绍了C语言的起源、发展及其标准化过程,涵盖了从早期的BCPL和B语言到现代C语言的演变,并探讨了其在操作系统和跨平台编程中的重要地位。 ... [详细]
  • 本文探讨了Java编程的核心要素,特别是其面向对象的特性,并详细介绍了Java虚拟机、类装载器体系结构、Java类文件和Java API等关键技术。这些技术使得Java成为一种功能强大且易于使用的编程语言。 ... [详细]
  • 对象自省自省在计算机编程领域里,是指在运行时判断一个对象的类型和能力。dir能够返回一个列表,列举了一个对象所拥有的属性和方法。my_list[ ... [详细]
  • 本文详细介绍了优化DB2数据库性能的多种方法,涵盖统计信息更新、缓冲池调整、日志缓冲区配置、应用程序堆大小设置、排序堆参数调整、代理程序管理、锁机制优化、活动应用程序限制、页清除程序配置、I/O服务器数量设定以及编入组提交数调整等方面。通过这些技术手段,可以显著提升数据库的运行效率和响应速度。 ... [详细]
  • 本文深入探讨了面向切面编程(AOP)的概念及其在Spring框架中的应用。通过详细解释AOP的核心术语和实现机制,帮助读者理解如何利用AOP提高代码的可维护性和开发效率。 ... [详细]
  • DCG 创始人兼首席执行官 Barry Silbert 发布致股东信,详细解答了 19 个核心问题,并分享了公司未来的发展方向。 ... [详细]
  • Hadoop发行版本选择指南:技术解析与应用实践
    本文详细介绍了Hadoop的不同发行版本及其特点,帮助读者根据实际需求选择最合适的Hadoop版本。内容涵盖Apache Hadoop、Cloudera CDH等主流版本的特性及应用场景。 ... [详细]
  • 目录一、salt-job管理#job存放数据目录#缓存时间设置#Others二、returns模块配置job数据入库#配置returns返回值信息#mysql安全设置#创建模块相关 ... [详细]
  • Nginx 反向代理与负载均衡实验
    本实验旨在通过配置 Nginx 实现反向代理和负载均衡,确保从北京本地代理服务器访问上海的 Web 服务器时,能够依次显示红、黄、绿三种颜色页面以验证负载均衡效果。 ... [详细]
  • 深入理解Vue.js:从入门到精通
    本文详细介绍了Vue.js的基础知识、安装方法、核心概念及实战案例,帮助开发者全面掌握这一流行的前端框架。 ... [详细]
author-avatar
豆伊一
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有