在导入路径中,@符号代表什么?

430

我正在开始一个新的vue.js项目,因此我使用vue-cli工具来脚手架生成一个新的webpack项目(即vue init webpack)。

当我浏览生成的文件时,我注意到在src/router/index.js文件中导入了以下内容:

import Vue from 'vue'
import Router from 'vue-router'
import Hello from '@/components/Hello' // <- this one is what my qusestion is about

Vue.use(Router)

export default new Router({
    routes: [
        {
            path: '/',
            name: 'Hello',
            component: Hello
        }
    ]
})

我以前没有在路径中看到过 @ 符号。我猜它允许使用相对路径(也许?),但我想确认一下它的确切作用。

我尝试在网上搜索,但没有找到解释(可能是因为搜索“@符号”或使用文字字符 @ 作为搜索条件不起作用)。

这个路径中的 @ 是什么意思(最好有链接说明),这是 ES6 的东西吗?Webpack 的东西?Vue-loader 的东西?

更新

感谢 Felix Kling 指向了另一个关于同样问题的重复 stackoverflow 问题/答案。

虽然其他 stackoverflow 帖子上的评论不是这个问题的确切答案(在我的情况下它不是 babel 插件),但它确实指导我找到了正确的方向。

在 vue-cli 创建的脚手架中,基本的 webpack 配置设置了一个别名用于 .vue 文件:

Alias location within project

这有道理,因为它给出了源文件的相对路径,并且它取消了导入路径结尾需要的 .vue 的要求。

感谢您的帮助!


4
看我的评论 - Felix Kling
4
这不是完全的重复,因为它没有回答整个问题,“这是ES6的事情吗?Webpack的事情?还是vue-loader的事情?” - Estus Flask
1
是的,我认为这个问题类似但并不重复。无论如何,我找出了它的来源,并在问题中更新了说明,因为我不能将其添加为答案。 - Chris Schmitz
1
@estus:答案非常清楚地表明它不是ES6的一部分,而是webpack配置的事情,你不觉得吗?这也正是这里的情况,只是配置的性质有点不同。 - Felix Kling
1
@FelixKling 这要看情况。但是,由于您链接的问题没有详细的答案来解释Webpack的情况,它可能值得回答。通常,在问题之间建立“可能是重复的...”评论就足以指示问题之间的联系,而大众的声音会起到作用。我在SO上经常看到问题被重复提出。 - Estus Flask
显示剩余5条评论
13个回答

375
这是通过Webpack配置选项resolve.alias实现的,与Vue无关。
在Vue Webpack模板中,Webpack被配置为使用src路径替换@/(原文链接)
  const path = require('path');

  ...
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      ...
      '@': path.resolve('src'),
    }
  },
  ...

别名用于:

import '@/<path inside src folder>';

259
JavaScript已经不再是原来的JavaScript了。使用Babel/webpack让我们拥有了这种混合怪物语言,而新手开发者却要知道ECMAScript规范的边界在哪里,以及用户自定义插件/转换器从何处开始。在我看来,这真的很悲哀。 - Mulan
3
用户可以选择是否将这些诀窍引入设置中。对于Vue来说并不是什么大问题,因为它依赖于其自定义的.vue文件格式。 - Estus Flask
29
个人认为,如果需要的话增加灵活性的能力是一件好事。我认为它更像是“超合金战记”,而不是“科学怪人”;你可以独立地操作一只狮子,或者组合不同的狮子来建造一个更大的机器人。是的,有时候会出现像这样的问题,但并不意味着找不到答案。实际上,在任何规模的项目中,你都可以采取“科学怪人”或“超合金战记”的视角,只需“使用和理解依赖关系”即可。 - Chris Schmitz
1
这取决于上下文和角度。像这样做会限制项目使用Webpack。如果项目计划在未来使用本地的ES6模块,或者是使用CommonJS作为模块的Node环境,可能不是一件好事。另一方面,长相对路径可能更难维护和重构。 - Estus Flask
8
在使用 vue-cli v3+ 时,应使用 ~@ 来引用 src 文件夹,例如:$font-path: '~@/assets/fonts/';。请注意不要改变原意,使翻译更通俗易懂。 - Consta Gorgan
显示剩余17条评论

36

请记住,您也可以在tsconfig中创建变量:

"paths": {
  "@components": ["src/components"],
  "@scss": ["src/styles/scss"],
  "@img": ["src/assests/images"],
  "@": ["src"],
}

这可以用于命名约定的目的:

import { componentHeader } from '@components/header';

但是这种别名在源JS中会被保留为空,然后在运行时,您需要有一个包装器介入以使别名起作用。也许有一种通过babel的方式可以将这个TS语法转换为编译时?使用TypeScript的tsc并不能做到这一点,因此您需要类似于module-aliastsconfig-paths的东西。 - ken
1
添加这个设置后,VS Code 无法解析路径,并且在单击导入的模块时无法进入文件。 - JackChouMine
我通常需要在哪个文件中定义“路径”对象? - user20984971

5
我使用以下组合完成了操作。
import HelloWorld from '@/components/HelloWorld'
=>
import HelloWorld from 'src/components/HelloWorld'

IDE将停止警告URI,但这会导致在“build\webpack.base.conf.js”编译时出现无效的URI。

resolve: {
  extensions: ['.js', '.vue', '.json'],
  alias: {
    'src': resolve('src'),
  }
},

Bingoo! (万岁!)

3

或许可以尝试添加webpack。 mix.webpackConfig 是参考 Laravel Mix 的。

mix.webpackConfig({

    resolve: {
        alias: {
            '@imgSrc': path.resolve('resources/assets/img')
        }
    }
});

然后在Vue中使用。

<img src="@imgSrc/logo.png" />

2

resolve('src') 对我无效, 但是 path.resolve('src') 有效。

resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': path.resolve('src')
    },
    extensions: ['*', '.js', '.vue', '.json']
  },

1
在Vue3和Vite中使用了类似的方法,可以在vite.config.js中找到别名。
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue(),vueJsx()],
  resolve: {
    alias: {
      "@": fileURLToPath(new URL("./src", import.meta.url)),
    },
  },
});

1
有些事情一定发生了变化。这里给出的答案已经不再正确。第9章中这个项目在其导入语句中使用了@符号,但是webpack.config.js文件没有路径解析语句:
let service = process.VUE_CLI_SERVICE

if (!service || process.env.VUE_CLI_API_MODE) {
  const Service = require('./lib/Service')
  service = new Service(process.env.VUE_CLI_CONTEXT || process.cwd())
  service.init(process.env.VUE_CLI_MODE || process.env.NODE_ENV)
}

module.exports = service.resolveWebpackConfig()

0
一个在 Next.js 中应用的例子是使用文件 next.config.js 来添加下一个内容。
const path = require('path');

module.exports = {
  webpack: (config, options) => {
    config.resolve.alias = {
      '@': path.resolve(process.cwd(), 'src'),
    };
    return config;
  }
};

0
有时我们使用 '@' 从一个路径为 "src/components/Add.vue" 的组件目录中导入。如果我们需要从不同的目录(如 "src/views/AboutView.vue")访问此文件,则可以在 AboutView.vue 中使用以下代码将 Add.vue 导入: import Add from "@/components/Add.vue", 放在你的

应该这样写:'@' 指的是你根目录下的 'src' 文件夹。 - Gayathri Raghuram

0

它指的是在您的config.js文件中找到的别名路径


2
嘿@jocoio,感谢您的加入并提供答案。看到新的贡献者想要帮助总是很棒的!我也想提供一些帮助:您的答案是正确的,但为了更好地帮助那些遇到问题的人,您可以提供更多的解释和背景信息。在这里查看其他答案,有许多很好的例子可供参考。再次感谢您的贡献。 - Chris Schmitz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接