Webpack'ing "sass"(dart-sass),使用需要动态、硬代码依赖到上下文中?

标签 webpack

问题

“sass”包包含一个模块,sass.dart.js:https://runpkg.com/?sass@1.21.0/sass.dart.js

除其他外,这包含 require 的动态用法(许多行已编辑):

var self = Object.create(global);
self.require = require;

//...

u($,"N0","Hq",function(){return self.require("readline")})
u($,"Mr","cN",function(){return self.require("fs")})
u($,"MN","Ho",function(){return self.require("chokidar")})

这种 require 的使用阻止了 webpack 的静态分析,导致输出错误(也在本要点中)并在 bundle 中创建了 webpackEmptyContext。这自然不行:)

尝试过的选项

我看过 ContextReplacementPlugin,我认为这不适用于此处,因为用法不是直接的 require 调用。

我见过 noParse,但这感觉像是核方法,我不知道潜在的负面影响是什么。

复制代码

也在 this gist

index.js:

const sass = require("sass");
console.log(sass);

webpack.config.js:

module.exports = (env) => ({
    entry: "./index.js",
    mode: "development",
    target: "node"
});

package.json:

{
  "devDependencies": {
    "webpack": "^4.34.0",
    "webpack-cli": "^3.3.4"
  },
  "dependencies": {
    "sass": "^1.21.0"
  },
  "scripts": {
    "build": "webpack-cli"
  }
}

目标

我如何配置这个特定模块的上下文以专门列出 readline/fs/chokidar 作为依赖项,可能会产生一些上下文只提供那些值?

我不介意解决方案是否有点脆弱并且需要固定 dart-sass 版本。

最佳答案

我们已经找到了一个“解决方案”,它实现了一个自定义的、特定于 dart-sass 的加载器,将代码添加到模块中以绕过静态分析。

sass-prepend-loader.js:

const SASS_PREPEND_CODE = `require = (function () {
  var fs = require("fs");
  var readline = require("readline");
  return function (mod) {
    switch (mod) {
      case "fs": return fs;
      case "readline": return readline;
      default: throw new Error("Unexpected sass dependency");
    }
  };
})();`

module.exports = function(source) {
    this.cacheable();
    this.callback(null, `${SASS_PREPEND_CODE}\n${source}`);
};

webpack.config.js(摘录):

module: {
    rules: [
        {
            resource: path.resolve(__dirname, "node_modules", "sass", "sass.dart.js"),
            loader: path.resolve(__dirname, "sass-prepend-loader.js"),
        }
    ],
},

这是专门为当前的“sass”版本 1.20.3 量身定制的,也可能是当前 webpack 中的行为。注意:我们没有通过“chokidar”依赖项,我们的用例不需要它。

它的工作原理是将只能提供“fs”和“readline”的版本分配给require。 Webpack 将 replace 替换为 __webpack_require__ 调用(满足其对静态分析的需求)并允许 require(现已隐藏)保留。

从 dist/index.js 中提取:

/***/ (function(module, exports, __webpack_require__) {

(function(module, exports, __webpack_require__) {

eval("/* WEBPACK VAR INJECTION */(function(__filename) {var require;require = (function () {\n  var fs = __webpack_require__(/*! fs */ \"fs\");\n  var readline = __webpack_require__(/*! readline */ \"readline\");\n  return function (mod) {\n    switch (mod) {\n      case \"fs\": return fs;\n      case \"readline\": return readline;\n      default: throw new Error(\"Unexpected sass dependency\");\n    }\n  };\n})();\n// make sure to keep this as 'var'\n// we don't want block scoping\nvar self = Object.create(global);\n\nself.scheduleImmediate = self.setImmediate\n    ? function (cb) {\n        global.setImmediate(cb);\n      }\n    : function(cb) {\n        setTimeout(cb, 0);\n      };\n\nself.require = require;

//...

self.require(\"fs\")

希望这是一个临时解决方案,我们可以通过以下途径之一得出更好的解决方案:

关于Webpack'ing "sass"(dart-sass),使用需要动态、硬代码依赖到上下文中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56653326/

相关文章:

javascript - 每次以不同的入口点运行 Webpack,但仍然使用配置文件?

laravel - 可以自动加载或 livereload npm run dev

javascript - 没有 iframe 的 Backbone 沙箱

javascript - 如何在我的 Webpack 项目中使用 Polyglot.js?

javascript - 找不到模块 : Error: Can't resolve './node_modules/react' in '/Users/<user-name>/Documents/gift-test/client'

javascript - VUE JS WEBPACK项目中如何通过&lt;script&gt;标签自动将NPM "dependencies"包含到index.html中?

javascript - Framework 7 Webpack 构建错误超过最大值 "500KB"

angular - 每次我在 .ts 文件中添加断点时,Chrome 都会烦人地在 main.bundle.ts 中打开相应的行

webpack - 如何让 Tree Shaking 在 React 库 "material-ui"的 Webpack 4 中工作?

node.js - 在 webpack 构建期间登录到 Node 控制台或调试