Vue CLI 学习笔记

组成

@vue/cli

@vue/cli 是一个全局安装的 npm 包,提供了终端里的全局 vue 命令。

安装:

npm install -g @vue/cli

命令:

vue --version
vue ui
vue create
vue serve # 使用该命令需要另外全局安装 `@vue/cli-service-global` 包
vue build # 使用该命令需要另外全局安装 `@vue/cli-service-global` 包

@vue/cli-service-global

@vue/cli-service-global 是一个全局安装的 npm 包,使用 vue servevue build 命令时需要安装这个包。

安装:

npm install -g @vue/cli-service-global

命令:

vue serve
vue build

@vue/cli-service

@vue/cli-service 是一个局部安装的 npm 包,自动安装在每个 @vue/cli 创建的项目中。

  • 提供项目内部的 vue-cli-service 命令
  • 构建于 webpack 和 webpack-dev-server 之上,拥有优化过的 webpack 配置
  • 加载 package.json 中列出的所有 @vue/cli-plugin-vue-cli-plugin- 插件

命令:

npx vue-cli-service help
npx vue-cli-service serve
npx vue-cli-service build
npx vue-cli-service inspect
npx vue-cli-service lint
"scripts": {
  "serve": "vue-cli-service serve",
  "build": "vue-cli-service build",
  "lint": "vue-cli-service lint"
}

@vue/cli-plugin- 和 vue-cli-plugin-

@vue/cli-plugin- 开头的是内建插件,vue-cli-plugin- 开头的是社区插件。

插件是局部安装的 npm 包,提供可选功能,例如 Babel/TypeScript 转译、ESLint 集成、单元测试和 end-to-end 测试等。

插件可以修改 webpack 的内部配置,也可以向 vue-cli-service 注入命令,当你在项目内部运行 vue-cli-service 命令时,它会自动解析并加载 package.json 中列出的所有插件。

preset

preset 是一个包含创建新项目所需预定义选项和插件的 JSON 对象,让用户无需在命令提示中选择它们,保存在 ~/.vuerc,可以直接修改。

命令

vue serve

我用不到

vue build

我用不到

vue create

使用命令行创建一个新项目

vue create hello-world

vue ui

使用图形化界面创建一个项目

vue ui

vue add

在现有的项目中安装插件

vue add @vue/cli-plugin-eslint

vue-cli-service serve

vue-cli-service serve 命令会启动一个基于 webpack-dev-server 的开发服务器。

命令:

npx vue-cli-service serve

配置:

  • 使用命令行参数配置 devServer
  • 使用 vue.config.js 里的 devServer 字段配置 devServer(推荐)

vue-cli-service build

vue-cli-service build 基于 webpack 将应用程序打包。

静态资源

在 .vue 组件中的 template 块、script 块、style 块中都可以引入静态资源。

<template>
  <div class="my-component">
    <img src="URL">
  </div>
</template>

<script>
import 'URL'
</script>

<style>
.my-component {
    background: url('URL');
}
</style>

静态资源路径可以是:

  • 绝对路径 /images/foo.png
  • 相对路径 ./images/foo.png
  • 模块路径 ~some_module/images/foo.png
  • 别名路径 @/images/foo.png
  • 放在 public 目录中

绝对路径

如果 URL 是一个绝对路径,在 <template> 标签中和在 <script> <style> 标签中的处理方式不同。

<template> 标签中,绝对路径会原样保留,对应的资源不会经过 webpack 打包,甚至都不会去查找是否有对应的资源,只是原样复制绝对路径到生成的 index.html 文件中。

<template>
  <div id="app">
    <img src="/images/foo.png">
  </div>
</template>

最后生成的 index.html 文件中,<img src="/images/foo.png">,这时候服务器的根目录下如果没有 images/foo.png,就会找不到资源。

这种情况都是配合 public 目录使用的,由于 public 目录中的所有资源都不会被 webpack 处理,只会原封不动地复制到 dist 目录中,因此位于 public/images/foo.png 的图片复制到了 dist/images/foo.png,只要将 dist 目录上传到服务器作为服务器的根目录,<img src="/images/foo.png"> 就能够访问到 dist/images/foo.png 了,也就是 public/images/foo.png 的拷贝。

<script><style> 标签中,绝对路径会以项目目录作为根目录,去查找对应的资源。

<script>
import '/images/foo.png'
</script>

<style>
.container {
  background: url('/images/foo.png')
}
</style>

以上会查找 <projectDirectory>/images/foo.png,如果存在资源,则该资源将会被包含进入 webpack 的依赖图中,通过 webpack 的 Assets Modules 配置,用版本哈希值和正确的公共基础路径来决定最终的文件路径,并将小于 8KiB 的资源内联,以减少 HTTP 请求的数量。

如果找不到该资源,则会报错。

相对路径

如果 URL 以 . 开头,它会作为一个相对模块请求,相对于当前的文件所处的目录。

import './images/foo.png'

<img src="./images/foo.png">

.container {
  background: url('./images/foo.png')
}

该资源将会被包含进入 webpack 的依赖图中,通过 webpack 的 Assets Modules 配置,用版本哈希值和正确的公共基础路径来决定最终的文件路径,并将小于 8KiB 的资源内联,以减少 HTTP 请求的数量。

模块路径

如果 URL 以 ~ 开头,其后的任何内容都会作为一个模块请求被解析,这意味着你甚至可以引用 Node 模块中的资源。

import '~some-npm-package/foo.png'

<img src="~some-npm-package/foo.png">

.container {
    background: url('~some-npm-package/foo.png')
}

该资源将会被包含进入 webpack 的依赖图中,通过 webpack 的 Assets Modules 配置,用版本哈希值和正确的公共基础路径来决定最终的文件路径,并将小于 8KiB 的资源内联,以减少 HTTP 请求的数量。

别名路径

如果 URL 以 @ 开头,它也会作为一个模块请求被解析。它的用处在于 Vue CLI 默认会设置一个指向 <projectRoot>/src 的别名 @。(仅作用于模版中)。注意在 css 中需要在 @ 前面加上 ~。

import '@/assets/images/1.png'

<img src="@/assets/images/1.png">

.container {
    background: url('~@/assets/images/1.png')
}

该资源将会被包含进入 webpack 的依赖图中,通过 webpack 的 Assets Modules 配置,用版本哈希值和正确的公共基础路径来决定最终的文件路径,并将小于 8KiB 的资源内联,以减少 HTTP 请求的数量。

public 目录

任何放置在 public 文件夹的静态资源都会被简单的复制到 dist 目录下,而不经过 webpack。你只能在 <template> 中通过绝对路径来引用它们。推荐将静态资源作为模块的依赖导入,而不是放置到 public 文件夹。

浏览器兼容性

vue 默认配置的 babel-loader 使用 @babel/preset-env 来进行转换语法,并通过配置 @babel/preset-env 的 useBuiltIns: 'usage' 选项来按需补齐 API。

vue 默认不会对 node_modules 目录里的模块使用 babel-loader,只会对我们的项目代码使用 babel-loader。

如果 node_modules 里面某个具体的依赖包需要使用 babel-loader 来转码,那么需要如下配置:

  1. 如果该依赖包需要语法转换和补齐 API,那么将 vue.config.js 的 transpileDependencies 选项指定具体依赖包,则 babel-loader 会对该依赖包进行语法转换和补齐 API。
// vue.config.js
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: ['jquery', 'lodash']
})
  1. 如果该依赖包不需要语法转换,只需要补齐 API,分以下两种情况:
  • 如果明确知道依赖包需要的 API,那么将 babel.config.js 的 @vue/babel-preset-app 的 polyfills 选项指定需要包含的 polyfills,这样不管源代码中是需要,都会引入该选项指定的 API。
// babel.config.js
module.exports = {
  presets: [
    [
      '@vue/babel-preset-app',
      {
        polyfills: [
          'es.promise',
          'es.symbol'
        ]
      }
    ]
  ]
}
  • 如果不知道依赖包具体需要哪些 API,那么设置 babel.config.js 的 @vue/babel-preset-app 的选项 useBuiltIns: 'entry',然后在项目入口文件开头 import 'core-js/stable'; import 'regenerator-runtime/runtime'; 一次性引入所有的 API,不按需引入了。
// babel.config.js
module.exports = {
  presets: [
    [
      '@vue/babel-preset-app',
      {
        useBuiltIns: 'entry' 
      }
    ]
  ]
}
// entry
import 'core-js/stable';
import 'regenerator-runtime/runtime';

mode 和环境变量

mode

vue-cli-service build mode 默认为 production
vue-cli-service serve mode 默认为 development
vue-cli-service test mode 默认为 test
可以通过 --mode 来改变 mode 默认值
vue-cli-service build --mode development

NODE_ENV

.env 文件中设置环境变量,可以设置 NODE_ENV 这个变量的值。如果没有 .env 目录中没有设置 NODE_ENV,则 NODE_ENV 默认等于 mode 值。

webpack 配置文件是根据 NODE_ENV 的值来配置的,例如 NODE_ENV 为 production,则 webpack 配置文件采用 splitChunks 配置,webpack 配置文件不是根据 mode 的值来决定配置的。

vue.config.js 和项目文件中都可以访问 process.env.NODE_ENV。vue.config.js 当中使用的 .env 中的 NODE_ENV 的值,而项目文件中使用的是在 vue.config.js 通过 DefinePlugin 定义的 process.env.NODE_ENV 的值,vue 会自动通过 DefinePlugin 定义 process.env.NODE_ENV 的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,194评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,058评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,780评论 0 346
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,388评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,430评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,764评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,907评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,679评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,122评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,459评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,605评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,270评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,867评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,734评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,961评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,297评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,472评论 2 348

推荐阅读更多精彩内容