有没有办法要求一个文件多次作为不同的模块

时间:2016-12-29 11:32:42

标签: javascript node.js webpack

我需要在.js和.less文件之间共享一个常量。我的解决方案包含两个步骤:

  1. 创建一个包含所有共享功能的.const扩展名的单独文件。它具有javascript模块语法,并将正常执行。
  2. 创建一个加载程序,根据需要此源的文件的扩展名来更改源代码。因此,例如,如果需要.less文件,则代码转换为较少的表达式
  3. 但我找不到根据需要模块从一个源文件创建两个模块的方法。

    我的条件加载器的源代码,用来做这些事情:

    module.exports = function(content, sourceMap) {
        var _ = require('lodash');
        var loaderUtils = require('loader-utils');
        var reasonResource = this._module.reasons[0].module.resource;
        var reasonResourceExtension = _.last(reasonResource.split('.'));
    
        switch (reasonResourceExtension)
        {
            case 'js':
            case 'const':
                var query = loaderUtils.parseQuery(this.query);
                if(query.cacheable && this.cacheable)
                    this.cacheable();
    
                return content;
                break;
            case 'less':
                var consts = this.exec(content, this.resource);
    
                return JSON.stringify(consts);
                break;
            default:
                throw new Error('Not supported import .const modules from ' + reasonResourceExtension.green);
        }
    };
    

2 个答案:

答案 0 :(得分:0)

您可以使用require loader语法在较少的文件中指定一个json-to-less加载器(不确定是否存在,但不应该很难编写):

@import "!json-to-less-loader!constants.json";

然后只需创建一个较少的文件(constants.less)来进行此导入并公开常量。从那里,您可以正常导入constants.less

我能够找到一个相反的加载器(less-to-json-loader)。所以你可以使用它并将你的常量存储在.less文件中并创建一个constants.js文件来导入和公开constants.less中的常量:

constants.less

@test: 20rem;
@test2: @test/2;

constants.js

module.exports = require("!less-to-json-loader!./constants.less");

答案 1 :(得分:0)

问题出在webpack.config.js。它不适用于less-loader中配置的加载器。所以解决方案是增加参数化Constants.const加载器列表

的能力

Pull request

然后可以用内容

编写export.modules = { debug: true }
Utilities.less

然后在@import (reference) 'Const.const';

中要求它
module.exports = function(content, sourceMap) {
    var _ = require('lodash');
    var loaderUtils = require('loader-utils');
    var reasonResource = this._module.reasons[0].module.resource;
    var reasonResourceExtension = _.last(reasonResource.split('.'));
    var query = loaderUtils.parseQuery(this.query);

    switch (reasonResourceExtension)
    {
        case 'js':
        case 'const':
            if(query.cacheable && this.cacheable)
                this.cacheable();

            return content;
            break;
        case 'less':
            if(query.cacheable && this.cacheable)
                this.cacheable();

            var consts = this.exec(content, this.resource);
            var str = '';
            (function append(consts, prefix = '')
            {
                for (var key in consts)
                {
                    let value = consts[key];
                    if (value.constructor != Object) {
                        str += '@' + prefix + key + ': ' + toLessCssValue(consts[key]) + ';';
                    } else {
                        throw new Error('Nested objects not supported in .const files');
                    }
                }
            }(consts));

            return str;
            break;
        default:
            throw new Error('Not supported import .const modules from ' + reasonResourceExtension.green);
    }

    function toLessCssValue(value) {
        if (isNaN(value)) {
            return value;
        } else {
            return 'unit(' + value + ', px)';
        }
    }
};

应用此加载器

{{1}}