Repository nuxt.js

How can I define stylus options?

Phunky
5
Phunky
commented 2 years ago

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.

0
desislavsd
50
desislavsd
commented 10 months ago

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')
          ]
        })
      },
}
7
Atinux
20.7k
Atinux
commented 2 years ago

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?

0
Phunky
5
Phunky
commented 2 years ago

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']
        }
      }
    }
  }
0
Atinux
20.7k
Atinux
commented 2 years ago

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

1
Phunky
5
Phunky
commented 2 years ago

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

0
Phunky
5
Phunky
commented 2 years ago

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

0
Atinux
20.7k
Atinux
commented 2 years ago

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

0
Phunky
5
Phunky
commented 2 years ago

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

I just add my imports directly into the loader.

0
Atinux
20.7k
Atinux
commented 2 years ago

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']
        }
      }) 
    ]
}
0
Phunky
5
Phunky
commented 2 years ago

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' } 
  ]`
0
Atinux
20.7k
Atinux
commented 2 years ago

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 šŸ‘

0
max-schu
35
max-schu
commented 2 years ago

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}
      }
    })
  ]
}
0
Phunky
5
Phunky
commented 2 years ago

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

0
max-schu
35
max-schu
commented 2 years ago

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?

0
Atinux
20.7k
Atinux
commented 2 years ago

You can via build.extend @max-schu

0
max-schu
35
max-schu
commented 2 years ago

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.

0
Atinux
20.7k
Atinux
commented 2 years ago

@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
    }
  }
}
0
max-schu
35
max-schu
commented 2 years ago

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.

0
TareqElMasri
0
TareqElMasri
commented 2 years ago

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

0
TareqElMasri
0
TareqElMasri
commented 2 years ago

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}`; 
  }
}
0
max-schu
35
max-schu
commented 2 years ago

@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.

1
desislavsd
50
desislavsd
commented 10 months ago

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')
          ]
        })
      },
}
7
gloomyline
0
gloomyline
commented 8 months ago

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

0
gianniskarmas
0
gianniskarmas
commented 7 months ago

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

0
mrkswrnr
0
mrkswrnr
commented 5 months ago

@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);
                });
              }
            });
          }
        });
      }
    }
  }
0
desislavsd
50
desislavsd
commented 4 months ago

@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)
}
0
Phunky
5
Phunky
commented 4 months ago

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ā€¦

1
gianniskarmas
0
gianniskarmas
commented 4 months ago

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