Webpack5 搭建 Vue3 + TS 项目

发表于 2年以前  | 总阅读数:866 次

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 四件套<span style="font-size: 15px;letter-spacing: 1px;">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-sfc, vue-loader 保持不变。 npm i vue-loader @vue/compiler-sfc --save-dev

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

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

<span style="font-size: 15px;letter-spacing: 1px;">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解析:

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

ts-loader 为单进程执行类型检查和转译,因此效率有些慢,可以用多进程方案:即关闭ts-loader的类型检查,类型检查由 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: 'ts-loader',
        options: {
          // 指定特定的ts编译配置,为了区分脚本的ts配置
          configFile: path.resolve(__dirname, '../tsconfig.loader.json'),
          // 对应文件添加个.ts或.tsx后缀
          appendTsSuffixTo: [/\.vue$/],
          transpileOnly: true, // ? 关闭类型检查,即只进行转译
        },
      },
    ],
}
// plugins push
new ForkTsCheckerWebpackPlugin()

至此项目基本可以跑起来了,那么有个问题了:Ts 可以编译为指定版本的 js,那么还需要 babel 么?

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

比如把箭头函数转成普通 function、aysnc + await 变成 Promise.then,这是语法转译;

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

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

Webpack 转译 Typescript 现有方案:

综合考虑性能和扩展性,目前比较推荐的是 babel+fork-ts-checker-webpack-plugin 方案。

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

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

那么,Babel 是如何处理 TypeScript 代码的呢?

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

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

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

添加 babel 解析 typescript

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

# 安装以下依赖 --save
@babel/runtime
@babel/runtime-corejs3
"core-js": "^3.11.0",

删除 ts-loader, 添加 babel-loader

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

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

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

4. 代码规范

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

5. 提交规范

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

npm i inquirer shelljs @commitlint/{cli,config-conventional} -D

添加 package.json 的 script :

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

创建 commit/git-commit.js 文件

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

async function gitCommit() {
  let { type } = await inquirer.prompt(prompsConfig.ciType)
  let { msg } = await inquirer.prompt(prompsConfig.ciMsg)

  shell.exec(`git commit -m "${type}: ${msg}"`, function () {
    console.log(`\n提交脚本: git commit -m "${type}: ${msg}"`)
  })
}

gitCommit()

配置 commitlint 类型,创建 commitlint.config.js 文件:

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

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

6. 构建部署 Travis CI

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

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

找到对应的仓库,打开开关添加仓库

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

点击对应仓库的 setting

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

创建 .travis.yml 配置文件:

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 上生成的令牌,允许 Travis 推送代码到你的仓库。
  # 在仓库对应的 Travis 设置页面中配置,用于安全控制。
  github_token: $GITHUB_TOKEN
  keep_history: true
  on:
    branch: master

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

7. 存在问题及总结

  • 构建时间比 webpack4 长,可能是由于 ts 的引入,以及 happypack 多进程构建的移除造成时间略长
  • dev server 不会自增 port
  • fork-ts-checker-webpack-plugin 无法检测 vue 中的 ts 类型错误

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

本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/eR-Rn1RKXZ8frz0RSZ87Ww

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:8月以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:8月以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:8月以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:8月以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:8月以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:8月以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:8月以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:8月以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:8月以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:8月以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:8月以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:8月以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:8月以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:8月以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:8月以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:8月以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:8月以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:8月以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:8月以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:8月以前  |  398次阅读  |  详细内容 »
 目录