Didn't find a word about this on the documentation, so I can't resolve this issue by myself.
So I started my project with vue-cli using vue init webpack projectname, and started fiddling around. As far as I understand, the app starting point is src/App.vue, which wraps components together.
So the style-block there is the "global" styles, that I can use to create "universal" styles available in every component, as it isn't scoped, but I'm having an issue with variables. The variables I create aren't available in other templates:
App.vue:
<style lang="stylus">
@import 'jeet'
colors = {
gray: #222,
red: rgb(255, 0, 0)
}
body{
background: colors.gray // works fine
}
</style>
components/Navigation.vue:
<style scoped lang="stylus">
// the scoped attribute doesn't make a difference, the variable doesn't work.
header{
background: colors.gray
}
</style>
See where I'm going here? It's probably an error on my part, but how am I supposed to create variables that are available in every template?
The same goes for plugins such as jeet. I think I can deal with it if I _have_ to @import 'jeet' in every style block, but I'd rather not if I don't have to. The traditional way that I used to do looks like this:
app.styl:
@import 'jeet'
colors = {
gray: #222
red: rgb(255, 0, 0)
}
@import 'header'
@import 'article'
...
So I kinda expected it to work a bit like this. Obviously it doesn't, but as I said, I didn't find a word about this in the documentation. Might be worth mentioning that this is the first time I'm using webpack, as I was happy with rollup and npm scripts.
E:I stumbled upon this (http://vuejs-templates.github.io/webpack/pre-processors.html#standalone-css-files) but it wasn't what I'm looking for. The global styles work just fine in it, but even if I define my variables (or stylus hashes) or @import 'jeet', the build fails if I try to use them inside templates.
I got a suggestion to use separate file for variables and @import them in each template. Sounds okay to me as a workaround, but I'd still like to know if there's an actual way of doing what I want to do.
I think I just opened this exact same issue and after doing some research, it looks like the official answer is that you do have to specifically @import in every component. I don't like that approach as it violates DRY but would love to hear if there are any plans to provide this functionality in the future.
I'm not exactly fond of it either, but I went with the compromise solution.
So I structured it like this:
src/
assets/
components/
styles/
fonts.styl
variables.styl
App.vue
main.js
variables.styl:
@import 'jeet';
colors = {
gray: #505456,
green: #35b768,
dark_green: #186655
}
Now if I intend to add more plugins or variables, I just add them there, instead of adding them to every style component. Not as DRY as it could be, but definitely not as WET as it would be should I add @import 'jeet' to every block.
Not that it would make any sense anyway with variables.
Closing as this is not a vue-loader bug. See also #328
It makes sense to have an isolated scope for style using vue-loader, in the same way you import the javascript you need in every component.
If you need global variable and mixins injection, you can use the stylus.import property of your webpack configuration:
stylus: {
import: [path.resolve(__dirname, '../src/styles/variables.styl')]
}
its works for me, thanks
@rayfranco i think you have the right answer , but i don't know how to setting in vue-cli .my webpack.base.conf.js setting like that
module: {
rules: [{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test')],
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 100,
name: utils.assetsPath('img/[name].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 100,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
}
so what should i do
@jessguo You should modify your webpack.base.config.js some like this:
var path = require('path')
var utils = require('./utils')
var config = require('../config')
var webpack = require('webpack')
var vueLoaderConfig = require('./vue-loader.conf')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
module.exports = {
entry: {
app: './src/main.js'
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src')
}
},
module: {
rules: [
{
test: /.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test')]
},
{
test: /.(png|jpe?g|gif|svg)(?.)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /.(woff2?|eot|ttf|otf)(?.)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
],
},
plugins: [
new webpack.LoaderOptionsPlugin({
options: {
stylus: {
use: [require('nib')()],
import: ['~nib/lib/nib/index.styl']
}
}
})
],
}
Facing this issue while using vuejs webpack boilerplate, I found how to modify the configuration files to make it work. See my answer at stackoverflow:
https://stackoverflow.com/questions/46854853/parseerror-expected-indent-got/49366987#49366987
It makes sense to have an isolated scope for
styleusingvue-loader, in the same way you import the javascript you need in every component.If you need global variable and mixins injection, you can use the
stylus.importproperty of your webpack configuration:stylus: { import: [path.resolve(__dirname, '../src/styles/variables.styl')] }
It works for me))
Most helpful comment
It makes sense to have an isolated scope for
styleusingvue-loader, in the same way you import the javascript you need in every component.If you need global variable and mixins injection, you can use the
stylus.importproperty of your webpack configuration: