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

How can I define stylus options? #148

Closed
Phunky opened this issue Jan 19, 2017 · 32 comments
Closed

How can I define stylus options? #148

Phunky opened this issue Jan 19, 2017 · 32 comments

Comments

@Phunky
Copy link

Phunky commented Jan 19, 2017

I import various helpers (mixins, vars, functions) into my component automatically to ensure they're always available to me and my team.

Currently I do this by setting the stylus import option within the webpack config as shown below;

stylus: { import: ['~stylus/common.styl'] }

I've not been able to figure out how to do this with nuxt, but i'll admit i've not looked deeply into the source myself to see how things are working, I'm hoping this is possible just yet to be documented.

This question is available on Nuxt.js community (#c126)
@Atinux
Copy link
Member

Atinux commented Jan 19, 2017

Hi @Phunky

You can extend the webpack configuration via the extend option in your nuxt.config.js:

module.exports = {
  build: {
     extend (config, { isDev, isClient }) {
       // ...
     }
  }
}

But where do you want to write your stylus: { import: ['~stylus/common.styl'] } in the webpack configuration?

@Phunky
Copy link
Author

Phunky commented Jan 19, 2017

Thank you for the pointer, I didn't stumble on to anything regarding extending webpack config - guess I need to RTFM better.

As for where I write my import, it's within build/webpack.base.conf.js so i'm assuming I'll want this;

  module.exports = {
    build: {
      extend (config, { isDev, isClient }) {
        config.stylus = {
          import: ['~stylus/common.styl']
        }
      }
    }
  }

@Atinux
Copy link
Member

Atinux commented Jan 19, 2017

No worries @Phunky, the documentation is not finished yet!

@Atinux Atinux closed this as completed Jan 19, 2017
@Phunky
Copy link
Author

Phunky commented Jan 19, 2017

Oh sadly what I posted above doesn't work, i'm seeing the following;

WebpackOptionsValidationError: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.

I'm guessing it's to do with the changes in Webpack 2.2.0

@Phunky
Copy link
Author

Phunky commented Jan 24, 2017

Still struggling with this, i've looked at option plugins and other various parts of webpack but had no luck at all :(

Only way i've got it working so far is to dive in to style-loader in node_modules and add it to the import array directly, this obviously isn't a good idea :D

@Atinux
Copy link
Member

Atinux commented Jan 24, 2017

@Phunky can you tell me what file do you update manually for making it work exactly?

@Phunky
Copy link
Author

Phunky commented Jan 24, 2017

https://github.com/shama/stylus-loader/blob/master/index.js#L33

I just add my imports directly into the loader.

@Atinux
Copy link
Member

Atinux commented Jan 24, 2017

Can you try with the webpack.LoaderOptionsPlugin or stylusLoader.OptionsPlugin (see there).

You can add them in the nuxt.config.js in the build.plugins section:

const stylusLoader = require('stylus-loader')

module.exports = {
  build: {
    plugins: [
      new stylusLoader.OptionsPlugin({
        default: {
          import: ['~stylus/common.styl']
        }
      }) 
    ]
}

@Phunky
Copy link
Author

Phunky commented Jan 24, 2017

I've already tried that and although the build works it doesn't seem to be passing the options.

config.plugins ends up looking like

`[ OptionsPlugin {
    plugin: 
     LoaderOptionsPlugin {
       options: 
        { stylus: { default: { import: [ '~assets/stylus/common.styl' ] } },
          test: /\.styl$/ } } },
  DefinePlugin {
    definitions: 
     { 'process.env.NODE_ENV': '"development"',
       'process.BROWSER_BUILD': true,
       'process.SERVER_BUILD': false } },
  CommonsChunkPlugin {
    chunkNames: 'vendor',
    filenameTemplate: 'vendor.bundle.js',
    minChunks: undefined,
    selectedChunks: undefined,
    async: undefined,
    minSize: undefined,
    ident: '/Users/phunky/Development/nuxt/node_modules/webpack/lib/optimize/CommonsChunkPlugin.js4' } 
  ]`

@Atinux
Copy link
Member

Atinux commented Jan 27, 2017

I let this issue closed since it's related to stylus-loader itself.

@Phunky you can post the solution when the team behind stylus-loader will have answered 👍

@max-schu
Copy link

max-schu commented Mar 27, 2017

asking to reopen this, i don't think it's a stylus loader issue.
trying to set includePaths with sass loader and it doesn't work.

const webpack = require('webpack')
const neat = require('node-neat').includePaths
build: {
  plugins: [
    new webpack.LoaderOptionsPlugin({
      options: {
        sassLoader: {includePaths: neat}
      }
    })
  ]
}

@Phunky
Copy link
Author

Phunky commented Mar 27, 2017

I did manage to get it working with

build: { plugins: [ new webpack.LoaderOptionsPlugin({ options: { stylus: { preferPathResolver: 'webpack', import: ['~assets/stylus/common'] }, context: '/' } }), ] }

The context part was the key bit, no idea why though :D

@max-schu
Copy link

max-schu commented Mar 27, 2017

mhm I don't think these options work with sass-loader.
Still I think its strange… seems like vue-loader doesnt care about the loaderOptionsPlugin settings options for sass-loader

ist there a way to extend vueloader.config?

@Atinux
Copy link
Member

Atinux commented Mar 28, 2017

You can via build.extend @max-schu

@max-schu
Copy link

max-schu commented Mar 28, 2017

do you happen to have any kind of reference on that? I used build.extend for aliases, but when i tried to extend the vueloader.config, some vars, other configs loaded in there were missing.
In general, I already solved my problem, but i think it would be a nice move to provide a more detailed doc on manipulating the configs.

@Atinux
Copy link
Member

Atinux commented Mar 31, 2017

@max-schu you can extend the vueLoader like this:

nuxt.config.js

module.exports = {
  build: {
    extend (config) {
      let vueLoader = config.module.rules.find((rule) => rule.loader === 'vue-loader')
      // extend vueLoader here
    }
  }
}

@max-schu
Copy link

thank you, thats more or less what i did, but this will overwrite the whole nuxt vueloader.config won't it?
e.g. if you just want to pass options to sass-loader inside vue-loader, you'd have to rewrite the whole vueloader config just for that. seems inpractical to me, correct me if i'm wrong.

@TareqElMasriDev
Copy link

@max-schu how could you fix the problem? I can't seem to find any solution so far

@TareqElMasriDev
Copy link

TareqElMasriDev commented Apr 6, 2017

I made it work with both bourbon and bourbon-neat, despite that I second @max-schu with his opinion, despite I don't like this fix, it works perfectly. Here's what I did.

module.exports = {
  build: {
    extend (config) {
      // Reference: https://github.com/nuxt/nuxt.js/blob/master/lib/webpack/vue-loader.config.js#L12
      let vueStyleLoaders = config.module.rules.find((rule) => rule.loader === 'vue-loader').query.loaders
      // bourbon & bourbon neat include paths, separated by `&includePaths[]=`
      const extraIncludePaths = [
        require('bourbon').includePaths,
        require('bourbon-neat').includePaths
        // ...
      ].join('&includePaths[]=')
      // Apply extra includedPaths
      vueStyleLoaders.scss += `?includePaths[]=${extraIncludePaths}`; 
  }
}

@max-schu
Copy link

max-schu commented Apr 6, 2017

@TareqElMasri actually I ended up including neat without npm and just the plain files.
I occassionally run into similar problems with other modules that are not 100% compatible and the best solution for me is to include them without npm. Of course, that approach might not be the best for bigger teams.
thank you for providing a fix tho.

@desislavsd
Copy link

desislavsd commented Jan 15, 2018

I did the following to let stylus-loader make use of nib and rupture and some additional configs:

build: {
      extend (config, { isDev, isClient }) {
        
        // find the stylus loader
        var stylus = config.module.rules[0].options.loaders.stylus.find( e => e.loader == 'stylus-loader');

        // extend default options
        Object.assign(stylus.options, {
          import: [
            '~nib/index.styl',
            '~rupture/rupture/index.styl',
            // require my own configs and variables and mixins and ..
            path.resolve(__dirname, 'assets/config.styl')
          ]
        })
      },
}

@gloomyline
Copy link

@desislavsd thx a lot, i've resolved my problem.

@cliqer
Copy link

cliqer commented Apr 9, 2018

Any suggestions of how to load stylus plugins in nuxt-edge?
Things seem simplified but unfortunately the above configuration does not work.

@mrkswrnr
Copy link

mrkswrnr commented Jun 27, 2018

@gianniskarmas: This works for me in nuxt-edge (2.0.0-25500158.1b46a95):

build: {
    extend(config) {
      // Customize stylus loader
      const stylusRules = config.module.rules.find(rule => rule.test.toString().indexOf("styl") > -1)
      if(stylusRules && Array.isArray(stylusRules.oneOf)) {
        stylusRules.oneOf.forEach(one => {
          if (Array.isArray(one.use)) {
            one.use.forEach(u => {
              if (u.loader == "stylus-loader") {
                const stylusOptions = u.options;
                //Define your options here (stylusOptions.use, stylusOptions.import, ...)
                //e.g. add a plugin:
                const uses = stylusOptions.use = stylusOptions.use || [];
                uses.push(function(style) {
                  style.define("theme", theme, true);
                });
              }
            });
          }
        });
      }
    }
  }

@desislavsd
Copy link

desislavsd commented Jul 6, 2018

@gianniskarmas This is my variant for nuxt-edge

  /*
  ** Build configuration
  */
  build: {

    /*
    ** You can extend webpack config here
    */
    extend(config, ctx) {
      
      /*
      ** find all stylus configs
      */
      [].concat(...config.module.rules.find( e => e.test.toString().match(/\.styl/) ).oneOf.map(e => e.use.filter(e => e.loader == 'stylus-loader'))).forEach(stylus => {

        /*
        ** extend default options
        */
        Object.assign(stylus.options, {
          import: [
            p('assets/configs/nibfix.styl'),
            '~nib/lib/nib/index.styl',
            '~rupture/rupture/index.styl',
            p('assets/configs/vars.styl')
          ]
        })
      });
    }
  }

/**
 * Path.resolve alias curried with current directory (__dirname)
 * as first parameter
 */
function p(){
  return path.resolve(__dirname, ...arguments)
}

@Phunky
Copy link
Author

Phunky commented Jul 6, 2018

I've ended up doing this with webpack-chain and below is a snippet of how I do this with Quasar.

   /**
    * Override stylue-loader options to add default imports.
    */
    let stylus = {
        preferPathResolver: 'webpack',
        sourceMap: true,
        import: [
            '~css/variables/colours.styl',
            '~css/mixins/colours.styl'
        ]
    }
    /**
    * WTF no idea why we have to do this three times, but we do...
    * config.toString() is your lifeline here...
    */
    config.module.rule('stylus').oneOf('normal').use('stylus-loader').options(stylus)
    config.module.rule('stylus').oneOf('modules-query').use('stylus-loader').options(stylus)
    config.module.rule('stylus').oneOf('modules-ext').use('stylus-loader').options(stylus)

The biggest Aha! moment was using config.toString() which actually shows the chain for each part of the config, prior to that I just got lost...

@cliqer
Copy link

cliqer commented Jul 6, 2018

Thank you all but I still haven't found an elegant solution to load stylus and plugins for edge yet even thought I tried all your suggestions.

This works perfectly fine in 1.4:

build: {
  extend (config, { isDev, isClient }) {
    var stylus = config.module.rules[0].options.loaders.stylus.find( e => e.loader == 'stylus-loader');
    Object.assign(stylus.options, {
      import: [
        '~nib/index.styl',
        '~rupture/rupture/index.styl',
        '~jeet/jeet.styl'
      ]
    })
  },
}

but gives the following errors in edge (just the last few lines as the rest are of the same nature):

warning  in ./pages/index.vue?vue&type=style&index=0&id=2a183b29&lang=stylus&scoped=true

Module Warning (from ./node_modules/postcss-loader/lib/index.js):
(Emitted value instead of an instance of Error) postcss-preset-env: /Users/admin/Downloads/nuxt-swiper-io-master/node_modules/nib/lib/nib/flex.styl:16:8: You should write display: flex by final spec instead of display: box

 @ ./node_modules/vue-style-loader??ref--7-oneOf-1-0!./node_modules/css-loader??ref--7-oneOf-1-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/lib??ref--7-oneOf-1-2!./node_modules/stylus-loader??ref--7-oneOf-1-3!./node_modules/vue-loader/lib??vue-loader-options!./pages/index.vue?vue&type=style&index=0&id=2a183b29&lang=stylus&scoped=true 4:14-388 14:3-18:5 15:22-396
 @ ./pages/index.vue?vue&type=style&index=0&id=2a183b29&lang=stylus&scoped=true
 @ ./pages/index.vue
 @ ./.nuxt/router.js
 @ ./.nuxt/index.js
 @ ./.nuxt/client.js
 @ multi webpack-hot-middleware/client?name=client&reload=true&timeout=30000&path=/__webpack_hmr ./.nuxt/client.js

 ERROR  Failed to compile with 4 errors                                                                       10:54:56

These relative modules were not found:
* ./about.vue?vue&type=template&id=0a606064&scoped=true&lang=pug in ./pages/about.vue
* ./index.vue?vue&type=template&id=2a183b29&scoped=true&lang=pug in ./pages/index.vue
* ./default.vue?vue&type=template&id=314f53c6&lang=pug in ./layouts/default.vue
* ./Navbar.vue?vue&type=template&id=cfc91daa&lang=pug in ./components/Navbar.vue

package.json

{
  "name": "nuxt-swiper-io",
  "version": "1.0.0",
  "description": "Nuxt.js project",
  "author": "Protogon",
  "private": true,
  "bin": "nuxt start",
  "scripts": {
    "dev": "nuxt",
    "dev-debug": "node --inspect node_modules/.bin/nuxt",
    "build": "nuxt build",
    "prod": "NODE_ENV=production nuxt",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
    "precommit": "npm run lint"
  },
  "dependencies": {
    "@nuxtjs/component-cache": "^1.1.2",
    "@nuxtjs/font-awesome": "^1.0.3",
    "global": "^4.3.2",
    "npm": "^6.1.0",
    "nuxt-edge": "^2.0.0-25513462.d31aeaa",
    "swiper": "^4.3.3",
    "vue-awesome-swiper": "^3.1.3"
  },
  "devDependencies": {
    "babel-eslint": "^8.2.5",
    "eslint": "^5.0.1",
    "eslint-config-prettier": "^2.9.0",
    "eslint-plugin-prettier": "^2.6.2",
    "eslint-plugin-vue": "^4.5.0",
    "jeet": "^7.2.0",
    "nib": "^1.1.2",
    "prettier": "^1.13.7",
    "pug": "^2.0.3",
    "pug-loader": "^2.4.0",
    "rupture": "^0.7.1",
    "stylus": "^0.54.5",
    "stylus-loader": "^3.0.2"
  }
}

So the question is, what do I have to change on the above code as to make it compatible with edge?

@desislavsd
Copy link

desislavsd commented Jul 6, 2018

@gianniskarmas Will you please try without the nib library?

Also the error you provide doesn't look related to stylus configs :/

@cliqer
Copy link

cliqer commented Jul 6, 2018

OMG, Thank you @desislavsd. You pointed me to the right direction.
It was a pug problem with nuxt. Had to add pug-plain-loader and remove pug-loader, then used your concut solution.
The other warning was with nib; had to change box with flex...

Many Thanks,
this was bugging me for a couple of months now.

  build: {
    extend(config, {isDev,isClient}) {
        [].concat(...config.module.rules.find(e => e.test.toString().match(/\.styl/)).oneOf.map(e => e.use.filter(e => e.loader == 'stylus-loader'))).forEach(stylus => {
            Object.assign(stylus.options, {
                import: [
                    '~nib/index.styl',
                    '~rupture/rupture/index.styl',
                    '~jeet/jeet.styl'
                ]
            })
        });
    },
  }

@desislavsd
Copy link

Glad to hear! As you have already found the fix for the nib is to import following styles before importing the library itself:

//nibfix.styl

flex-version = flex
support-for-ie = false
vendor-prefixes = official
//nuxt.config.js

Object.assign(stylus.options, {
          import: [
            p('assets/configs/nibfix.styl'), // first import nibfix
            '~nib/lib/nib/index.styl',         // then the nib itself
            '~rupture/rupture/index.styl',
            p('assets/configs/vars.styl')
          ]
        })
       //...

Just to make it easier for the others ;)

@ghost
Copy link

ghost commented Jul 6, 2018

This question has been resolved by @desislavsd, see answer.

@ghost ghost added the cmty:status:resolved label Jul 6, 2018
@lock
Copy link

lock bot commented Nov 1, 2018

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Nov 1, 2018
@danielroe danielroe added the 2.x label Jan 18, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

9 participants