Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Variables not available in other templates #326

Closed
k1sul1 opened this issue Aug 26, 2016 · 9 comments
Closed

Variables not available in other templates #326

k1sul1 opened this issue Aug 26, 2016 · 9 comments

Comments

@k1sul1
Copy link

k1sul1 commented Aug 26, 2016

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.

@westwick
Copy link

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.

@k1sul1
Copy link
Author

k1sul1 commented Aug 29, 2016

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.

@LinusBorg
Copy link
Member

Closing as this is not a vue-loader bug. See also #328

@rayfranco
Copy link

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')]
}

@david-quintanilla
Copy link

its works for me, thanks

@jessguo
Copy link

jessguo commented Jul 3, 2017

@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

@david-quintanilla
Copy link

@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']
}
}
})
],
}

@qnp
Copy link

qnp commented Mar 19, 2018

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

@strukove
Copy link

strukove commented Jun 6, 2019

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')]
}

It works for me))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants