API 浏览器
Quasar CLI with Webpack - @quasar/app-webpack
应用资源处理

你会注意到在项目结构中我们有两个资源目录:/public//src/assets/。它们之间有什么区别?有些是静态资源,而其他则由构建系统处理和嵌入。

¥You will notice in the project structure we have two directories for assets: /public/ and /src/assets/. What is the difference between them? Some are static assets while the others are processed and embedded by the build system.

让我们尝试回答上面的问题。我们将首先讨论如何使用常规资源,然后了解静态资源的区别。

¥So let’s try to answer the question above. We’ll first talk about using regular assets then we’ll see what the difference is for static assets.

常规资源 - /src/assets(Regular assets - /src/assets)

¥Regular assets - /src/assets

*.vue 组件中,所有模板和 CSS 都会由 vue-html-loadercss-loader 解析以查找资源 URL。例如,在 <img src="./logo.png">background: url(./logo.png) 中,"./logo.png" 是一个相对资源路径,Webpack 会将其解析为模块依赖。

¥In *.vue components, all your templates and CSS are parsed by vue-html-loader and css-loader to look for asset URLs. For example, in <img src="./logo.png"> and background: url(./logo.png), "./logo.png" is a relative asset path and will be resolved by Webpack as a module dependency.

由于 logo.png 不是 JavaScript,因此当将其视为模块依赖时,我们需要使用 url-loaderfile-loader 来处理它。Quasar CLI 已经为你配置了这些 Webpack 加载器,因此你可以免费获得文件名指纹识别和条件性 base64 内联等功能,同时能够使用相对路径/模块路径,而无需担心部署问题。

¥Because logo.png is not JavaScript, when treated as a module dependency, we need to use url-loader and file-loader to process it. Quasar CLI has already configured these webpack loaders for you, so you basically get features such as filename fingerprinting and conditional base64 inlining for free, while being able to use relative/module paths without worrying about deployment.

由于这些资源在构建期间可能会被内联/复制/重命名,因此它们本质上是源代码的一部分。这就是为什么建议将 Webpack 处理过的资源文件与其他源文件一起放置在 /src/assets 中。实际上,你甚至不必将它们全部放在 /src/assets 中:你可以根据使用它们的模块/组件来组织它们。例如,你可以将每个组件放在其自己的目录中,并将其静态资源放在其旁边。

¥Since these assets may be inlined/copied/renamed during build, they are essentially part of your source code. This is why it is recommended to place Webpack-processed assets inside /src/assets, along side other source files. In fact, you don’t even have to put them all in /src/assets: you can organize them based on the module/component using them. For example, you can put each component in its own directory, with its static assets right next to it.

资源解析规则(Asset Resolving Rules)

¥Asset Resolving Rules

相对 URL,例如 ./assets/logo.png,将被解释为模块依赖。它们将被替换为基于 Webpack 输出配置自动生成的 URL。

¥Relative URLs, e.g. ./assets/logo.png will be interpreted as a module dependency. They will be replaced with an auto-generated URL based on your Webpack output configuration.

~ 为前缀的 URL 被视为模块请求,类似于 require('some-module/image.png')。如果你想利用 Webpack 的模块解析配置,则需要使用此前缀。Quasar 提供了开箱即用的 assets Webpack 别名,因此建议你像这样使用它:<img src="~assets/logo.png">。请注意 ~ 位于 ‘assets’ 之前。

¥URLs prefixed with ~ are treated as a module request, similar to require('some-module/image.png'). You need to use this prefix if you want to leverage Webpack’s module resolving configurations. Quasar provides assets Webpack alias out of the box, so it is recommended that you use it like this: <img src="~assets/logo.png">. Notice ~ in front of ‘assets’.

静态资源 - /public(Static Assets - /public)

¥Static Assets - /public

根目录相关的 URL(例如 /logo.png,其中 ‘/’ 是你的 publicPath)或 logo.png 根本不会处理。这应该放在 public/ 中。Webpack 根本不会处理这些 props。public 文件夹的内容将直接复制到可分发文件夹。

¥Root-relative URLs (e.g. /logo.png – where ‘/’ is your publicPath) or logo.png are not processed at all. This should be placed in public/. These won’t be processed by Webpack at all. The content of the public folder is simply copied over to the distributable folder as-is.

Quasar 背后有一些智能算法,可以确保无论你构建什么(SPA、PWA、Cordova、Electron),当且仅当你的静态变量不使用相对路径时,它们才会被正确引用。

¥Quasar has some smart algorithms behind the curtains which ensure that no matter what you build (SPA, PWA, Cordova, Electron), your statics are correctly referenced if and only if they do not use a relative path.

<!-- Good! -->
<img src="logo.png">

<!--
  BAD! Works until you change vue router
  mode (hash/history) or your public path.
  Don't!
-->
<img src="/logo.png">

资源 vs 静态资源

只有当 “assets” 文件夹中的文件在你的某个 Vue 文件中字面量引用时,它们才会包含在你的构建中。无论如何,“public” 文件夹中的每个文件和文件夹都会按原样复制到你的生产版本中。

¥Files in the “assets” folder are only included in your build if they have a literal reference in one of your Vue files. Every file and folder from the “public” folder are copied into your production build as-is, no matter what.

危险

如果未构建 SPA/PWA/SSR,则 /public/icons/*/public/favicon.ico 将不会嵌入到你的应用中,因为它们没有任何用途。例如,Electron 或 Cordova 应用不需要这些文件。

¥When not building a SPA/PWA/SSR, then /public/icons/* and /public/favicon.ico will NOT be embedded into your app because they would not serve any purpose. For example, Electron or Cordova apps do not require those files.

Vue 绑定仅需要静态变量(Vue Binding Requires Statics Only)

¥Vue Binding Requires Statics Only

请注意,每当你将 “src” 绑定到 Vue 作用域中的变量,必须来自 public 文件夹。原因很简单:URL 是动态的,因此 Webpack(在编译时打包资源)不知道你在运行时会引用哪个文件,所以它不会处理该 URL。

¥Please note that whenever you bind “src” to a variable in your Vue scope, it must be one from the public folder. The reason is simple: the URL is dynamic, so Webpack (which packs up assets at compile time) doesn’t know which file you’ll be referencing at runtime, so it won’t process the URL.

<template>
  <!-- imageSrc MUST reference a file from /public -->
  <img :src="imageSrc">
</template>

<script>
export default {
  setup () {
    return {
      /*
        Referencing /public.
        Notice string doesn't start with a slash. (/)
      */
      imageSrc: 'logo.png'
    }
  }
}
</script>

你可以通过使用 Vue 将 src 绑定到某个值来强制提供静态资源。不要使用 src="path/to/image",而要使用 :src=" 'path/to/image' ":src="imageSrc"。请注意第二个代码示例中双引号内单引号的用法(为了在文档网站上直观地查看,添加了空格 - 通常情况下不会出现空格)。

¥You can force serving static assets by binding src to a value with Vue. Instead of src="path/to/image" use :src=" 'path/to/image' " or :src="imageSrc". Please note the usage of single quotes within double quotes on the second code example (spaces have been added to see this visually on the documentation website - normally you would not have the spaces).

使用 JavaScript 获取资源路径(Getting Asset Paths in JavaScript)

¥Getting Asset Paths in JavaScript

为了使 Webpack 返回正确的资源路径,你需要使用 require('./relative/path/to/file.jpg'),它将由 file-loader 处理并返回解析后的 URL。例如:

¥In order for Webpack to return the correct asset paths, you need to use require('./relative/path/to/file.jpg'), which will get processed by file-loader and returns the resolved URL. For example:

computed: {
  background () {
    return require('./bgs/' + this.id + '.jpg')
  }
}

请注意,上述示例将在最终版本中包含 ./bgs/ 下的所有图片。这是因为 Webpack 无法猜测在运行时会使用哪些配置,所以它会将它们全部包含进去。

¥Note the above example will include every image under ./bgs/ in the final build. This is because Webpack cannot guess which of them will be used at runtime, so it includes them all.