If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeAs our app grows, there's going to be more and more directories and paths to think about. In products.vue
, we go up one directory to get to components
. And in sidebar
, we need to go up two directories to get to our CSS files. This isn't a huge deal, but it's only going to get worse as we add even more directories and sub-directories.
To help with this, the Vue world commonly uses a feature called Webpack aliases. Open up your webpack.config.js
file. It doesn't matter where... but I'll go after .enablesSingleRuntimeChunk()
, add .addAliases()
and pass an object. Add a key called @
set to path.resolve()
.
Oh, but stop right there: PhpStorm is mad! This path
thing is a core Node module and we need to require it first. At the top: var path = require('path')
.
The path.resolve()
function is the least important part of this whole process: it's a fancy way in Node to create a path. Pass it __dirname
- that's a Node variable that means "the directory of this file" - then assets
and finally js
.
... line 1 | |
var path = require('path'); | |
... lines 3 - 9 | |
Encore | |
... lines 11 - 38 | |
// This is our alias to the root vue components dir | |
.addAliases({ | |
'@': path.resolve(__dirname, 'assets', 'js'), | |
styles: path.resolve(__dirname, 'assets', 'scss'), | |
}) | |
... lines 44 - 104 |
Before I explain this, duplicate the line and create one more alias called styles
that points at the scss
directory. And... I don't need those quotes around styles
.
So... what the heck does this do? An alias is kind of like a fake directory. Thanks to this, when we import files in our code, we can prefix the path with @
and Webpack will know that we're referring to the assets/js
directory. We can do the same with styles/
: that's a shortcut to the assets/scss
directory.
Let's see this in action. First, because we just made a change to our Webpack config, at your terminal, hit Control + C to stop Encore and then restart it:
yarn dev-server --hot
Once that finishes.. just to be safe, let's refresh. Everything still works. Now let's use our shiny new, optional alias shortcut!
Start in products.vue
. Instead of ../
, which gets us up to the js/
directory, we can say @/components/catalog
... because @
is an alias to the same directory.
... lines 1 - 14 | |
<script> | |
import Catalog from '@/components/catalog'; | |
import Sidebar from '@/components/sidebar'; | |
... lines 18 - 25 | |
</script> |
The nice thing is that if we move our code to a different directory, this path will keep working: @
always points to the js/
folder.
We don't have to use this everywhere, but let's update a few other spots, like catalog.vue
. Same thing: @/components/legend
.
... lines 1 - 22 | |
<script> | |
import LegendComponent from '@/components/legend'; | |
... lines 25 - 36 | |
</script> |
And then in sidebar.vue
, it's a bit different. Down in the style
tag, we can use the styles
alias. But when you're inside CSS code and want to use an alias, you need one extra thing: a ~
prefix. So in this case, ~styles/components
.
... lines 1 - 35 | |
<style lang="scss" module> | |
@import '~styles/components/light-component'; | |
... lines 38 - 47 | |
</style> |
Oh, and I totally messed up! You can see a build error from Webpack. When I set up the styles
alias, the path should be scss
, not css
.
... lines 1 - 9 | |
Encore | |
... lines 11 - 39 | |
.addAliases({ | |
... line 41 | |
styles: path.resolve(__dirname, 'assets', 'scss'), | |
}) | |
... lines 44 - 104 |
Over at the terminal, here's the fully angry error: file to import not found or unreadable... because we gave it a bad path. I'll stop and restart Encore one more time:
yarn dev-server --hot
Now... it's happy! Let's update two more files to get a feel for this. Open products.js
. Instead of ./pages
, we can say @/pages
.
... line 1 | |
import App from '@/pages/products'; | |
... lines 3 - 7 |
And one more in app.js
. To load the CSS file, we can say styles/
and then we don't the scss
directory.
... lines 1 - 8 | |
import 'styles/app.scss'; |
But... maybe you were expecting me to say ~styles
like we did earlier? Here's the deal: when you're inside of a JavaScript file, you can just use the word styles
even if you referring to a CSS file. The ~
thing is only needed when you're doing the import from inside of CSS itself, like in the style
tag.
So... those are Webpack aliases. If you love them, great! If you think they're some sort of strange sorcery, don't use them. The @
alias is common in the Vue world. So at the very least, if you see Vue code importing @/something
, now you'll understand the dark magic that makes this work.
Next: let's see our second custom Vue syntax: the v-for
directive for looping.
Hey Lionel,
I'm really happy you found the solution! And thanks for sharing that if you set "Detect webpack configuration files for module resolution" option to "Automatically" in "Languages & Frameworks" -> "JavaScript" -> "Webpack" of PhpStorm's config helps :)
Cheers!
Hi, thanks for this tutorial. How do I make this work with TypeScript? I tried it with:
`
"baseUrl": "./",
"paths": {
"@": ["./assets/js"],
"styles": ["./assets/css"]
},
`
in my tsconfig.json, but it doesn't seem to work :(
Hey Gustavo!
When it comes to Vue 2, TypeScript is not recommended. There are issues with the Options API (the way we declare our components) and the magic "this" keyword that TypeScript is unable to type-check correctly.
However, if you still want to pursue TypeScript with this project, it seems like you would need to add TypeScript to Webpack Encore first, then configure the application's entry files to be processed correctly.
Here's some documentation: https://symfony.com/doc/current/frontend/encore/typescript.html
thanks for your answer, I'm already using Vue 3 and TypeScript on Encore, specifically these versions:<br />"@vue/compiler-sfc": "^3.0.0-rc.4",<br />"ts-loader": "^5.3.0",<br />"typescript": "^3.9.7",<br />"vue": "^3.0.0-rc.4",<br />"vue-loader": "^16.0.0-beta.4",<br />
and i was relying on this page...
https://v3.vuejs.org/guide/typescript-support.htm
No problem!
Could you share more details on your issue? What errors do you see? Does it generate the JavaScript files?
Finally, I found the problem, the correct setting in tsconfig.json is:
`
"baseUrl": "./assets",
"paths": {
"@/*": ["./js/*"],
"styles/*": ["./css/*"]
}
`
Thanks you!
// package.json
{
"devDependencies": {
"@symfony/webpack-encore": "^0.30.0", // 0.30.2
"axios": "^0.19.2", // 0.19.2
"bootstrap": "^4.4.1", // 4.5.0
"core-js": "^3.0.0", // 3.6.5
"eslint": "^6.7.2", // 6.8.0
"eslint-config-airbnb-base": "^14.0.0", // 14.1.0
"eslint-plugin-import": "^2.19.1", // 2.20.2
"eslint-plugin-vue": "^6.0.1", // 6.2.2
"regenerator-runtime": "^0.13.2", // 0.13.5
"sass": "^1.29.0", // 1.29.0
"sass-loader": "^8.0.0", // 8.0.2
"vue": "^2.6.11", // 2.6.11
"vue-loader": "^15.9.1", // 15.9.2
"vue-template-compiler": "^2.6.11", // 2.6.11
"webpack-notifier": "^1.6.0" // 1.8.0
}
}
Hi,
when i look the tutorial video I saw that on your Phpstorm you haven't got error on aliases, how you inform to Phpstorm that the aliases are not errors ? this is a special plugin you have ?