Skip to content
This repository has been archived by the owner on Jan 16, 2018. It is now read-only.

Loader query function, regex, and object, support #13

Open
colelawrence opened this issue Jul 9, 2015 · 5 comments
Open

Loader query function, regex, and object, support #13

colelawrence opened this issue Jul 9, 2015 · 5 comments

Comments

@colelawrence
Copy link

Currently, the loader query only supports strings, and when you pass it an actual object, it applies stringify to it, and prevents the ability to pass a function, which may be desirable if you wish to pass a custom minification function, or a regex to your loader.

Query to json string in /lib/LoadersList.js#L52-L61

function getLoadersFromObject(element) {
    if(element.query) {
        if(!element.loader || element.loader.indexOf("!") >= 0) throw new Error("Cannot define 'query' and multiple loaders in loaders list");
        if(typeof element.query === "string") return [element.loader + "?" + element.query];
        return [element.loader + "?" + JSON.stringify(element.query)];
    }
    if(element.loader) return element.loader.split("!");
    if(element.loaders) return element.loaders;
    throw new Error("Element from loaders list should have one of the fields 'loader' or 'loaders'");
}

jade-locals interpretting query: webpack/jade-loader/index.js#L9-L20

module.exports = function(source) {
    this.cacheable && this.cacheable();
    var jade = require("jade");

    var utils = require("jade/lib/utils");
    var nodes = require("jade/lib/nodes");
    var filters = require("jade/lib/filters");

    var req = loaderUtils.getRemainingRequest(this).replace(/^!/, "");

    var query = loaderUtils.parseQuery(this.query);

It is especially relevant for my current project where we need to pass in a localization function (convert keys to text) into the jade-loader locals object.

I feel this can be addressed by allowing element.query to be either an object or a string.

Maybe there is a way to work around this by allowing the list of loaders to be objects of the modules themselves, as described in webpack/How to register a custom loader in webpack.config #903 or where is apply-loader to use with jade-loader #940

@colelawrence
Copy link
Author

My config kinda looks like this:

  module: {
    loaders: [
      { test: /\.jsx?$/, loader: "ng-annotate-loader!babel-loader?stage=0", exclude: /web_modules|node_modules|bower_components/ },
      { test: /\.jade$/, loader: "jade-loader",
        query: {
          root: jadeOpts.basedir,
          locals: {
            localize: function (translation_key) {
              return translation_table[translation_key]
            }
          }
        }
      },

@colelawrence colelawrence changed the title Loader query function support Loader query function, regex, and object, support Jul 9, 2015
@colelawrence
Copy link
Author

I think I'm onto a really simple solution with:

  resolveLoader: {
    alias: {
      "jade-loader-wrapper": path.join(__dirname, "./jade-loader-wrapper")
    }
  },

Edit:
To quickly fix my specific scenario, I had to copy and paste the jade-loader/index.js and jade-loader/stringify.loader.js into my project directory where jade-loader-wrapper resolves to and hard-code configure it to use the local variables and functions I needed.

@colelawrence
Copy link
Author

Actually, this makes sense why jade locals can only be in json, because the default locals need to be transferred to the client's browser, for when you render the jade client-side with additional locals. However, in my case, (using this with angular templates) I modified my custom jade-loader to return the string of HTML using just jade.render with no special features.

  run();
  function run() {
    var string;
    if (query.renderHTML) {
      string = jade.render(source, {
        filename: req,
        self: query.self,
        pretty: query.pretty,
        basedir: jadeCommon.jadeOpts.basedir,
        locals: jadeCommon.jadeOpts.locals,
        compileDebug: loaderContext.debug || false
      });
    } else {
      try {
        var tmplFunc = jade.compileClient(source, {
          parser: loadModule ? MyParser : undefined,

ref original webpack/jade-loader/index#L165-L172

@MoOx
Copy link

MoOx commented Mar 18, 2016

This would be nice to have this in core. No need to stringify something that loader developer will consume as an object. Are you open for a PR to allow query to be a (real) object @sokra ?

@thangngoc89
Copy link

@MoOx webpack/core is decrapted in webpack@2

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

No branches or pull requests

3 participants