Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/433.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用自定义网页包加载器将额外字段附加到默认导出_Javascript_Webpack_Webpack Loader - Fatal编程技术网

Javascript 使用自定义网页包加载器将额外字段附加到默认导出

Javascript 使用自定义网页包加载器将额外字段附加到默认导出,javascript,webpack,webpack-loader,Javascript,Webpack,Webpack Loader,我正试图编写一个自定义的webpack加载程序,用于加载演示javascript文件及其源代码,以便于文档编制。它应该 加载指定的javascript文件(例如Simple.demo.js) 将文件的原始源作为新字段附加到默认导出 完成后,我应该能够在我的网页配置中配置加载程序: { test: /\.demo.js$/, exclude: /node_modules/, use: [{ loader: "babel-loader", }, {

我正试图编写一个自定义的webpack加载程序,用于加载演示javascript文件及其源代码,以便于文档编制。它应该

  • 加载指定的javascript文件(例如
    Simple.demo.js
  • 将文件的原始源作为新字段附加到默认导出
完成后,我应该能够在我的网页配置中配置加载程序:

{
    test: /\.demo.js$/,
    exclude: /node_modules/,
    use: [{
       loader: "babel-loader",
    }, {
       loader: resolve("./demo-loader.js"),
    }]
}
…然后在导入后访问我的演示的源代码:

import SimpleDemo from 'demo-loader!./Simple.demo.js';                  
console.log(SimpleDemo.__source__);
SimpleDemo(); //run the demo code
尝试1 我已使用以下加载程序成功加载原始源并完成命名导出:

const { readFile } = require("fs");
const escapeSource = require("js-string-escape");

module.exports = function withSourceLoader(content, map, meta) {
    const onComplete = this.async();
    const fileName = this.resource;
    readFile(fileName, (error, fileContents) => {
        if ( error ) {
            return onComplete(error);
        }
        const exportSource = `export const rawSource = "${ escapeSource(fileContents)}";`;
        const newContent = `${ content }\n\n${ exportSource }`;

        onComplete(null, newContent, map, meta);
    });
};
这让我做

import SimpleDemo, { rawSource } from 'demo-loader!./Simple.demo.js`;                  
console.log(rawSource);
SimpleDemo(); //run the demo code
…但是我想将整个
SimpleDemo
作为一个对象传递给另一个函数,所以我想将它们作为单个块导入(将有很多演示)

尝试2 因为我不知道演示文件中用于默认导出的内部变量名(不进行完整的AST解析),所以我不能只在文件中附加一行来修改它。相反,我尝试编写一个包装文件,导入并重新导出默认值,如下所示:

const { readFile } = require("fs");
const { basename } = require("path");
const escapeSource = require("js-string-escape");

module.exports = function withSourceLoader(content, map, meta) {
    const onComplete = this.async();
    const fileName = this.resource;
    readFile(fileName, (error, fileContents) => {
        if ( error ) {
            return onComplete(error);
        }
        const newContent = `
             const rawSource = "${ escapeSource(fileContents) }";
             import DemoDefault from './${ basename(fileName) }';
             DemoDefault.__source__ = rawSource;
             export default DemoDefault;
        `;

        onComplete(null, newContent, map, meta);
    });
};
我希望这个新的
import
指令能够通过webpack解决(我知道这可能会导致无限回归,因为它应该根据文件名再次触发相同的加载程序)。然而,这似乎并没有发生——我只是觉得

TypeError: _Simple_demo_js__WEBPACK_IMPORTED_MODULE_0__.default is undefined
这似乎是因为webpack已经构建了它的依赖关系树,不想向其中添加任何其他内容。我还尝试使用
require()
而不是
import
,这并没有改善问题


我走错方向了吗?我想通过组合其他加载程序的输出来使用一些简单的链接,但API似乎没有办法做到这一点。

找到了如何使用:


我的
require()
调用是如何解决问题的,现在还不是100%清楚,但它工作得很好!我计划在本周晚些时候以模块的形式发布(附带一些其他功能)。

我现在已将此加载程序作为一个包发布,附带一些额外的功能!
const { readFile } = require("fs");
const escapeSource = require("js-string-escape");
const { stringifyRequest } = require("loader-utils");

module.exports = function empty() { /* do nothing */ };

module.exports.pitch = function withSourceLoader(remainingRequest) {
    const onComplete = this.async();
    const filename = this.resource;
    readFile(filename, (error, fileContents) => {
        if ( error ) {
            return onComplete(error);
        }
        const newContent = `        
            module.exports = require(${stringifyRequest(this, "!!" + remainingRequest)});
            const rawSource = "${ escapeSource(fileContents) }";
            module.exports.default.__source__ = rawSource;
        `;

        onComplete(null, newContent);
    });
};