Vue CLI 官方文档(三)模式和环境变量(--mode,.env)、构建目标(--target)、部署

叶浩荡
2023-12-01

Vue CLI 官方文档(三)模式和环境变量(–mode,.env)、构建目标(–target)、部署

1. 模式和环境变量

模式

模式是 Vue CLI 项目中一个重要的概念。默认情况下,一个 Vue CLI 项目有三个模式

  • development 模式用于 vue-cli-service serve
  • test 模式用于 vue-cli-service test:unit
  • production 模式用于 vue-cli-service buildvue-cli-service test:e2e

你可以通过传递 --mode 选项参数为命令行覆写默认的模式。例如,如果你想要在构建命令中使用开发环境变量:

vue-cli-service build --mode development

当运行 vue-cli-service 命令时,所有的环境变量都从对应的环境文件中载入。如果文件内部不包含 NODE_ENV 变量,它的值将取决于模式,例如,在 production 模式下被设置为 "production",在 test 模式下被设置为 "test",默认则是 "development"

NODE_ENV 将决定您的应用运行的模式,是开发,生产还是测试,因此也决定了创建哪种 webpack 配置。

例如通过将 NODE_ENV 设置为 "test",Vue CLI 会创建一个优化过后的,并且旨在用于单元测试的 webpack 配置,它并不会处理图片以及一些对单元测试非必需的其他资源。

同理,NODE_ENV=development 创建一个 webpack 配置,该配置启用热更新,不会对资源进行 hash 也不会打出 vendor bundles,目的是为了在开发的时候能够快速重新构建。

当你运行 vue-cli-service build 命令时,无论你要部署到哪个环境,应该始终把 NODE_ENV 设置为 "production" 来获取可用于部署的应用程序

NODE_ENV

如果在环境中有默认的 NODE_ENV,你应该移除它或在运行 vue-cli-service 命令的时候明确地设置 NODE_ENV

环境变量

你可以在你的项目根目录中放置下列文件来指定环境变量:

.env                # 在所有的环境中被载入
.env.local          # 在所有的环境中被载入,但会被 git 忽略
.env.[mode]         # 只在指定的模式中被载入
.env.[mode].local   # 只在指定的模式中被载入,但会被 git 忽略

一个环境文件只包含环境变量的“键=值”对

FOO=bar
VUE_APP_NOT_SECRET_CODE=some_value

警告

不要在你的应用程序中存储任何机密信息(例如私有 API 密钥)!

环境变量会随着构建打包嵌入到输出代码,意味着任何人都有机会能够看到它

请注意,只有 NODE_ENVBASE_URL 和以 VUE_APP_ 开头的变量将通过 webpack.DefinePlugin 静态地嵌入到客户端侧的代码中。这是为了避免意外公开机器上可能具有相同名称的私钥

想要了解解析环境文件规则的细节,请参考 dotenv。我们也使用 dotenv-expand 来实现变量扩展 (Vue CLI 3.5+ 支持)。例如:

FOO=foo
BAR=bar

CONCAT=$FOO$BAR # CONCAT=foobar

被载入的变量将会对 vue-cli-service 的所有命令、插件和依赖可用。

环境文件加载优先级

为一个特定模式准备的环境文件 (例如 .env.production) 将会比一般的环境文件 (例如 .env) 拥有更高的优先级。

此外,Vue CLI 启动时已经存在的环境变量拥有最高优先级,并不会被 .env 文件覆写。

.env 环境文件是通过运行 vue-cli-service 命令载入的,因此环境文件发生变化,你需要重启服务。

示例:Staging 模式

假设我们有一个应用包含以下 .env 文件:

VUE_APP_TITLE=My App

.env.staging 文件:

NODE_ENV=production
VUE_APP_TITLE=My App (staging)
  • vue-cli-service build 会加载可能存在的 .env.env.production.env.production.local 文件然后构建出生产环境应用。
  • vue-cli-service build --mode staging 会在 staging 模式下加载可能存在的 .env.env.staging.env.staging.local 文件然后构建出生产环境应用。

这两种情况下,根据 NODE_ENV,构建出的应用都是生产环境应用,但是在 staging 版本中,process.env.VUE_APP_TITLE 被覆写成了另一个值。

在客户端侧代码中使用环境变量

只有以 VUE_APP_ 开头的变量会被 webpack.DefinePlugin 静态嵌入到客户端侧的包中。你可以在应用的代码中这样访问它们:

console.log(process.env.VUE_APP_SECRET)

在构建过程中,process.env.VUE_APP_SECRET 将会被相应的值所取代。在 VUE_APP_SECRET=secret 的情况下,它会被替换为 "secret"

除了 VUE_APP_* 变量之外,在你的应用代码中始终可用的还有两个特殊的变量:

  • NODE_ENV - 会是 "development""production""test" 中的一个。具体的值取决于应用运行的模式
  • BASE_URL - 会和 vue.config.js 中的 publicPath 选项相符,即你的应用会部署到的基础路径。

所有解析出来的环境变量都可以在 public/index.html 中以 HTML 插值中介绍的方式使用。

提示

你可以在 vue.config.js 文件中计算环境变量。它们仍然需要以 VUE_APP_ 前缀开头。这可以用于版本信息:

process.env.VUE_APP_VERSION = require('./package.json').version

module.exports = {
  // config
}

只在本地有效的变量

有的时候你可能有一些不应该提交到代码仓库中的变量,尤其是当你的项目托管在公共仓库时。这种情况下你应该使用一个 .env.local 文件取而代之。本地环境文件默认会被忽略,且出现在 .gitignore 中。

.local 也可以加在指定模式的环境文件上,比如 .env.development.local 将会在 development 模式下被载入,且被 git 忽略。

2. 构建目标

当你运行 vue-cli-service build 时,你可以通过 --target 选项指定不同的构建目标。它允许你将相同的源代码根据不同的用例生成不同的构建

应用

应用模式是默认的模式。在这个模式中:

  • index.html 会带有注入的资源和 resource hint
  • 第三方库会被分到一个独立包以便更好的缓存
  • 小于 4kb 的静态资源会被内联在 JavaScript 中
  • public 中的静态资源会被复制到输出目录中

关于 IE 兼容性的提醒

在库模式中,项目的 publicPath 是根据主文件的加载路径动态设置的(用以支持动态的资源加载能力)。但是这个功能用到了 document.currentScript,而 IE 浏览器并不支持这一特性。所以如果网站需要支持 IE 的话,建议使用库之前先在页面上引入 current-script-polyfill

注意对 Vue 的依赖

在库模式中,Vue 是外置的。这意味着包中不会有 Vue,即便你在代码中导入了 Vue。如果这个库会通过一个打包器使用,它将尝试通过打包器以依赖的方式加载 Vue;否则就会回退到一个全局的 Vue 变量。

要避免此行为,可以在build命令中添加--inline-vue标志。

vue-cli-service build --target lib --inline-vue

你可以通过下面的命令将一个单独的入口构建为一个库:

vue-cli-service build --target lib --name myLib [entry]
File                     Size                     Gzipped

dist/myLib.umd.min.js    13.28 kb                 8.42 kb
dist/myLib.umd.js        20.95 kb                 10.22 kb
dist/myLib.common.js     20.57 kb                 10.09 kb
dist/myLib.css           0.33 kb                  0.23 kb

这个入口可以是一个 .js 或一个 .vue 文件。如果没有指定入口,则会使用 src/App.vue

构建一个库会输出:

  • dist/myLib.common.js:一个给打包器用的 CommonJS 包 (不幸的是,webpack 目前还并没有支持 ES modules 输出格式的包)
  • dist/myLib.umd.js:一个直接给浏览器或 AMD loader 使用的 UMD 包
  • dist/myLib.umd.min.js:压缩后的 UMD 构建版本
  • dist/myLib.css:提取出来的 CSS 文件 (可以通过在 vue.config.js 中设置 css: { extract: false } 强制内联)

警告

如果你在开发一个库或多项目仓库 (monorepo),请注意导入 CSS 是具有副作用的。请确保在 package.json移除 "sideEffects": false,否则 CSS 代码块会在生产环境构建时被 webpack 丢掉。

Vue vs. JS/TS 入口文件

当使用一个 .vue 文件作为入口时,你的库会直接暴露这个 Vue 组件本身,因为组件始终是默认导出的内容

然而,当你使用一个 .js.ts 文件作为入口时,它可能会包含具名导出,所以库会暴露为一个模块。也就是说你的库必须在 UMD 构建中通过 window.yourLib.default 访问,或在 CommonJS 构建中通过 const myLib = require('mylib').default 访问。如果你没有任何具名导出并希望直接暴露默认导出,你可以在 vue.config.js 中使用以下 webpack 配置:

module.exports = {
  configureWebpack: {
    output: {
      libraryExport: 'default'
    }
  }
}

Web Components 组件

兼容性提示

Web Components 模式不支持 IE11 及更低版本。更多细节

注意对 Vue 的依赖

在 Web Components 模式中,Vue 是外置的。这意味着包中不会有 Vue,即便你在代码中导入了 Vue。这里的包会假设在页面中已经有一个可用的全局变量 Vue

你可以通过下面的命令将一个单独的入口构建为一个 Web Components 组件:

vue-cli-service build --target wc --name my-element [entry]

注意这里的入口应该是一个 *.vue 文件。Vue CLI 将会把这个组件自动包裹并注册为 Web Components 组件,无需在 main.js 里自行注册。也可以在开发时把 main.js 作为 demo app 单独使用。

该构建将会产生一个单独的 JavaScript 文件 (及其压缩后的版本) 将所有的东西都内联起来。当这个脚本被引入网页时,会注册自定义组件 <my-element>,其使用 @vue/web-component-wrapper 包裹了目标的 Vue 组件。这个包裹器会自动代理属性、特性、事件和插槽。请查阅 @vue/web-component-wrapper 的文档了解更多细节。

注意这个包依赖了在页面上全局可用的 Vue

这个模式允许你的组件的使用者以一个普通 DOM 元素的方式使用这个 Vue 组件:

<script src="https://unpkg.com/vue"></script>
<script src="path/to/my-element.js"></script>

<!-- 可在普通 HTML 中或者其它任何框架中使用 -->
<my-element></my-element>

注册多个 Web Components 组件的包

当你构建一个 Web Components 组件包的时候,你也可以使用一个 glob 表达式作为入口指定多个组件目标:

vue-cli-service build --target wc --name foo 'src/components/*.vue'

当你构建多个 web component 时,--name 将会用于设置前缀,同时自定义元素的名称会由组件的文件名推导得出。比如一个名为 HelloWorld.vue 的组件携带 --name foo 将会生成的自定义元素名为 <foo-hello-world>

异步 Web Components 组件

当指定多个 Web Components 组件作为目标时,这个包可能会变得非常大,并且用户可能只想使用你的包中注册的一部分组件。这时异步 Web Components 模式会生成一个 code-split 的包,带一个只提供所有组件共享的运行时,并预先注册所有的自定义组件小入口文件。一个组件真正的实现只会在页面中用到自定义元素相应的一个实例时按需获取:

vue-cli-service build --target wc-async --name foo 'src/components/*.vue'
File                Size                        Gzipped

dist/foo.0.min.js    12.80 kb                    8.09 kb
dist/foo.min.js      7.45 kb                     3.17 kb
dist/foo.1.min.js    2.91 kb                     1.02 kb
dist/foo.js          22.51 kb                    6.67 kb
dist/foo.0.js        17.27 kb                    8.83 kb
dist/foo.1.js        5.24 kb                     1.64 kb

现在用户在该页面上只需要引入 Vue 和这个入口文件即可:

<script src="https://unpkg.com/vue"></script>
<script src="path/to/foo.min.js"></script>

<!-- foo-one 的实现的 chunk 会在用到的时候自动获取 -->
<foo-one></foo-one>

在构建时使用 vuex

在构建 Web Components 组件时,入口点不是 main.js ,而是 entry-wc.js 文件,该文件由此生成: https://github.com/vuejs/vue-cli/blob/dev/packages/%40vue/cli-service/lib/commands/build/resolveWcEntry.js

因此,要在 Web Components 组件的目标中使用 vuex ,你需要在 App.vue 中初始化存储 (store):

import store from './store'

// ...

export default {
  store,
  name: 'App',
  // ...
}

3. 部署

通用指南

如果你用 Vue CLI 处理静态资源并和后端框架一起作为部署的一部分,那么你需要的仅仅是确保 Vue CLI 生成的构建文件在正确的位置,并遵循后端框架的发布方式即可。

如果你独立于后端部署前端应用——也就是说后端暴露一个前端可访问的 API,然后前端实际上是纯静态应用。那么你可以将 dist 目录里构建的内容部署到任何静态文件服务器中,但要确保正确的 publicPath

本地预览

dist 目录需要启动一个 HTTP 服务器来访问 (除非你已经将 publicPath 配置为了一个相对的值),所以以 file:// 协议直接打开 dist/index.html 是不会工作的。在本地预览生产环境构建最简单的方式就是使用一个 Node.js 静态文件服务器,例如 serve

npm install -g serve
# -s 参数的意思是将其架设在 Single-Page Application 模式下
# 这个模式会处理即将提到的路由问题
serve -s dist

使用 history.pushState 的路由

如果你在 history 模式下使用 Vue Router,是无法搭配简单的静态文件服务器的。例如,如果你使用 Vue Router 为 /todos/42/ 定义了一个路由,开发服务器已经配置了相应的 localhost:3000/todos/42 响应,但是一个为生产环境构建架设的简单的静态服务器会却会返回 404。

为了解决这个问题,你需要配置生产环境服务器,将任何没有匹配到静态文件的请求回退到 index.html。Vue Router 的文档提供了常用服务器配置指引

CORS

如果前端静态内容是部署在与后端 API 不同的域名上,你需要适当地配置 CORS

PWA

如果你使用了 PWA 插件,那么应用必须架设在 HTTPS 上,这样 Service Worker 才能被正确注册。

平台指南

云开发 CloudBase

云开发 CloudBase 是一个云原生一体化的 Serverless 云平台,支持静态网站、容器等多种托管能力,并提供简便的部署工具 CloudBase Framework) 来一键部署应用。

步骤一:安装云开发 CloudBase CLI

CloudBase CLI 集成了 CloudBase Framework) 的能力,全局安装 CloudBase CLI 请运行以下命令:

npm install -g @cloudbase/cli

步骤二:一键部署

在项目根目录运行以下命令部署 Vue CLI 创建的应用,在部署之前可以先 开通环境

cloudbase init --without-template
cloudbase framework:deploy

CloudBase CLI 首先跳转到控制台进行登录授权,然后将会交互式进行以下步骤

  • 选择一个环境,如果没有可以选择新建环境
  • 自动检测项目并确认构建脚本,输出目录、部署云端路径等信息

确认信息后会立即进行部署,部署完成后,可以获得一个自动 SSL,CDN 加速的网站应用,你也可以搭配使用 Github Action 来持续部署 Github 上的 Vue 应用。

混合部署

除了部署一个纯静态的 Vue CLI 项目之外,还可以快速一键部署混合的全栈 Vue 应用:

  • 使用 cloudbase init --template vue 快速创建和部署一个包含 Serverless 云函数后端的 Vue 应用
  • 使用 cloudbase init --template nuxt-ssr 快速创建和部署一个包含 SSR 和 Serverless 云函数后端的 Vue 应用

详细信息请查看 CloudBase Framework 的部署项目示例

GitHub Pages

手动推送更新

  1. vue.config.js 中设置正确的 publicPath

    如果打算将项目部署到 https://<USERNAME>.github.io/ 上, publicPath 将默认被设为 "/",你可以忽略这个参数。

    如果打算将项目部署到 https://<USERNAME>.github.io/<REPO>/ 上 (即仓库地址为 https://github.com/<USERNAME>/<REPO>),可将 publicPath 设为 "/<REPO>/"。举个例子,如果仓库名字为“my-project”,那么 vue.config.js 的内容应如下所示:

    module.exports = {
      publicPath: process.env.NODE_ENV === 'production'
        ? '/my-project/'
        : '/'
    }
    
  2. 在项目目录下,创建内容如下的 deploy.sh (可以适当地取消注释) 并运行它以进行部署:

    #!/usr/bin/env sh
    
    # 当发生错误时中止脚本
    set -e
    
    # 构建
    npm run build
    
    # cd 到构建输出的目录下 
    cd dist
    
    # 部署到自定义域域名
    # echo 'www.example.com' > CNAME
    
    git init
    git add -A
    git commit -m 'deploy'
    
    # 部署到 https://<USERNAME>.github.io
    # git push -f git@github.com:<USERNAME>/<USERNAME>.github.io.git master
    
    # 部署到 https://<USERNAME>.github.io/<REPO>
    # git push -f git@github.com:<USERNAME>/<REPO>.git master:gh-pages
    
    cd -
    

使用 Travis CI 自动更新

  1. 仿照上面在 vue.config.js 中设置正确的 publicPath

  2. 安装 Travis CLI 客户端:gem install travis && travis --login

  3. 生成一个拥有“repo”权限的 GitHub 访问令牌

  4. 授予 Travis 访问仓库的权限:travis set GITHUB_TOKEN=xxx (xxx 是第三步中的个人访问令牌)

  5. 在项目根目录下创建一个 .travis.yml 文件。

    language: node_js
    node_js:
      - "node"
    
    cache: npm
    
    script: npm run build
    
    deploy:
    provider: pages
    skip_cleanup: true
    github_token: $GITHUB_TOKEN
    local_dir: dist
    on:
      branch: master
    
  6. .travis.yml 文件推送到仓库来触发第一次构建。

GitLab Pages

根据 GitLab Pages 文档的描述,所有的配置都在根目录中的.gitlab-ci.yml 文件中。下面的范例是一个很好的入门:

# .gitlab-ci.yml 文件应放在你仓库的根目录下 

pages: # 必须定义一个名为 pages 的 job
  image: node:latest
  stage: deploy
  script:
    - npm ci
    - npm run build
    - mv public public-vue # GitLab Pages 的钩子设置在 public 文件夹
    - mv dist public # 重命名 dist 文件夹 (npm run build 之后的输出位置)
  artifacts:
    paths:
      - public # artifact path 一定要在 /public , 这样 GitLab Pages 才能获取
  only:
    - master

通常, 你的静态页面将托管在 https://yourUserName.gitlab.io/yourProjectName 上, 所以你可以创建一个 initial vue.config.js 文件去 更新 BASE_URL 要匹配的值 :

// vue.config.js 位于仓库的根目录下
// 确保用 GitLab 项目的名称替换了 `YourProjectName`

module.exports = {
  publicPath: process.env.NODE_ENV === 'production'
    ? '/yourProjectName/'
    : '/'
}

请阅读在 GitLab Pages domains 的文档来学习更多关于页面部署 URL 的信息。注意,你也可以使用自定义域名

在推送到仓库之前提交 .gitlab-ci.ymlvue.config.js 文件。GitLab CI 的管道将会被触发: 当成功时候, 到 Settings > Pages 查看关于网站的链接。

Netlify

  1. 在 Netlify 上,使用以下设置从 GitHub 创建新项目:
    • 构建命令: npm run buildyarn build
    • 发布目录: dist
  2. 点击“deploy”按钮!

也可以查看 vue-cli-plugin-netlify-lambda

如果使用 Vue Router 的 history 模式,你需要在 /public 目录下创建一个 _redirects 文件:

# 单页应用的 Netlify 设置
/*    /index.html   200

详细信息请查看 Netlify 重定向文档

Render

Render 提供带有全托管 SSL,全球 CDN 和 GitHub 持续自动部署的免费静态站点托管服务。

  1. 在 Render 上创建一个新的 Web Service,并授予 Render 的 GitHub 应用访问你的 Vue 仓库的权限。
  2. 在创建过程中使用以下设置:
    • 环境Static Site
    • 构建命令npm run build 或者 yarn build
    • 发布目录dist

大功告成!构建结束时你的应用便会在你的 Render URL 上线。

如果使用 Vue Router 的 history 模式,你需要在站点的 Redirects/Rewrites 设置中添加以下改写规则:

  • Source: /*
  • Destination: /index.html
  • Status: Rewrite

详细信息请查看 Render 的重定向和改写自定义域名文档。

Amazon S3

参见 vue-cli-plugin-s3-deploy

Firebase

创建一个新的 Firebase 项目 Firebase console。 请参考文档

确保已经全局安装了 firebase-tools

npm install -g firebase-tools

在项目的根目录下, 用以下命令初始化 firebase

firebase init

Firebase 将会询问有关初始化项目的一些问题。

  • 选择需要 Firebase CLI 的功能。 一定要选择 hosting
  • 选择默认的 Firebase 项目。
  • public 目录设为 dist (或构建输出的位置) 这将会上传到 Firebase Hosting。
// firebase.json

{
  "hosting": {
    "public": "dist"
  }
}
  • 选择 yes 设置项目为一个单页应用。 这将会创建一个 index.htmldist 文件夹并且配置 hosting 信息。
// firebase.json

{
  "hosting": {
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}

执行 npm run build 去构建项目。

Firebase Hosting 部署项目,执行以下命令 :

firebase deploy --only hosting

如果需要在部署的项目中使用的其他 Firebase CLI 功能, 执行 firebase deploy 去掉 --only 参数。

现在可以到 https://<YOUR-PROJECT-ID>.firebaseapp.com 访问你的项目了。

请参考 Firebase 文档 来获取更多细节。

Vercel

Vercel 是一个网站和无服务器 (Serverless) API 云平台,你可以使用你的个人域名 (或是免费的 .vercel.app URL) 部署你的 Vue 项目。

步骤一:安装 Now CLI

要使用 npm 安装其命令行界面,运行以下命令:

npm install -g vercel

步骤二:部署

在项目根目录运行以下命令部署你的应用:

vercel

此外,你还可以使用他们的 GitHubGitLab 集成服务。

大功告成!

你的站点会开始部署,你将获得一个形如 https://vue.now-examples.now.sh/ (或.vercel.app)的链接。

开箱即用地,请求会被自动改写到 index.html (除了自定义的静态文件) 并带有合适的缓存请求头。

Stdlib

未完成 | 欢迎参与贡献。

Heroku

  1. 安装 Heroku CLI

  2. 创建 static.json 文件:

    {
      "root": "dist",
      "clean_urls": true,
      "routes": {
        "/**": "index.html"
      }
    }
    
  3. static.json 加入 Git

    git add static.json
    git commit -m "add static configuration"
    
  4. 部署到 Heroku

    heroku login
    heroku create
    heroku buildpacks:add heroku/nodejs
    heroku buildpacks:add https://github.com/heroku/heroku-buildpack-static
    git push heroku master
    

详细信息:https://gist.github.com/hone/24b06869b4c1eca701f9

Surge

要使用 Surge 进行部署,步骤非常简单。

首先,通过运行 npm run build 来构建项目。如果还没有安装 Surge 的命令行工具,可以通过运行命令来执行此操作:

npm install --global surge

然后 cd 进入项目的 dist/ 文件夹,然后运行 surge 并按照屏幕提示操作 。如果是第一次使用 Surge,它会要求设置电子邮件和密码。确认项目文件夹以及输入首选域来查看正在部署的项目,如下所示。

            project: /Users/user/Documents/myawesomeproject/dist/
         domain: myawesomeproject.surge.sh
         upload: [====================] 100% eta: 0.0s (31 files, 494256 bytes)
            CDN: [====================] 100%
             IP: **.**.***.***

   Success! - Published to myawesomeproject.surge.sh

通过访问 myawesomeproject.surge.sh 来确保你的项目已经成功的用 Surge 发布,有关自定义域名等更多设置详细信息,可以到 Surge’s help page 查看。

Bitbucket Cloud

  1. Bitbucket 文档 创建一个命名为 <USERNAME>.bitbucket.io 的仓库。

  2. 如果你想拥有多个网站, 想要发布到主仓库的子文件夹中。这种情况下就要在 vue.config.js 设置 publicPath

    如果部署到 https://<USERNAME>.bitbucket.io/publicPath 默认将被设为 "/",你可以选择忽略它。

    如果要部署到 https://<USERNAME>.bitbucket.io/<SUBFOLDER>/,设置 publicPath"/<SUBFOLDER>/"。在这种情况下,仓库的目录结构应该反映 url 结构,例如仓库应该有 /<SUBFOLDER> 目录。

  3. 在项目中, deploy.sh 使用以下内容创建并运行它以进行部署:

    #!/usr/bin/env sh
    
    # 当发生错误时中止脚本
    set -e
    
    # 构建
    npm run build
    
    # cd 到构建输出的目录
    cd dist
    
    git init
    git add -A
    git commit -m 'deploy'
    
    git push -f git@bitbucket.org:<USERNAME>/<USERNAME>.bitbucket.io.git master
    
    cd -
    

Docker (Nginx)

在 Docker 容器中使用 Nginx 部署你的应用。

  1. 安装 Docker

  2. 在项目根目录创建 Dockerfile 文件

    FROM node:10
    COPY ./ /app
    WORKDIR /app
    RUN npm install && npm run build
    
    FROM nginx
    RUN mkdir /app
    COPY --from=0 /app/dist /app
    COPY nginx.conf /etc/nginx/nginx.conf
    
  3. 在项目根目录创建 .dockerignore 文件

    设置 .dockerignore 文件能防止 node_modules 和其他中间构建产物被复制到镜像中导致构建问题。

    **/node_modules
    **/dist
    
  4. 在项目根目录创建 nginx.conf 文件

    Nginx 是一个能在 Docker 容器中运行的 HTTP(s) 服务器。它使用配置文件决定如何提供内容、要监听的端口等。参阅 Nginx 设置文档 以了解所有可能的设置选项。

    下面是一个简单的 Nginx 设置文件,它会在 80 端口上提供你的 Vue 项目。页面未找到 / 404 错误使用的是 index.html,这让我们可以使用基于 pushState() 的路由。

    user  nginx;
    worker_processes  1;
    error_log  /var/log/nginx/error.log warn;
    pid        /var/run/nginx.pid;
    events {
      worker_connections  1024;
    }
    http {
      include       /etc/nginx/mime.types;
      default_type  application/octet-stream;
      log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                        '$status $body_bytes_sent "$http_referer" '
                        '"$http_user_agent" "$http_x_forwarded_for"';
      access_log  /var/log/nginx/access.log  main;
      sendfile        on;
      keepalive_timeout  65;
      server {
        listen       80;
        server_name  localhost;
        location / {
          root   /app;
          index  index.html;
          try_files $uri $uri/ /index.html;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
          root   /usr/share/nginx/html;
        }
      }
    }
    
  5. 构建你的 Docker 镜像

    docker build . -t my-app
    # Sending build context to Docker daemon  884.7kB
    # ...
    # Successfully built 4b00e5ee82ae
    # Successfully tagged my-app:latest
    
  6. 运行你的 Docker 镜像

    这个例子基于官方 Nginx 镜像,因此已经设置了日志重定向并关闭了自我守护进程。它也提供了其他有利于 Nginx 在 Docker 容器中运行的默认设置。更多信息参阅 Nginx Docker 仓库

    docker run -d -p 8080:80 my-app
    curl localhost:8080
    # <!DOCTYPE html><html lang=en>...</html>
    
 类似资料: