首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Webpack‘’ing "sass“(dart-sass),使用需要动态,硬代码依赖到上下文?

Webpack‘’ing "sass“(dart-sass),使用需要动态,硬代码依赖到上下文?
EN

Stack Overflow用户
提问于 2019-06-19 00:19:43
回答 1查看 559关注 0票数 2

问题

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

此外,它还包含require的动态用法(编辑了许多行):

代码语言:javascript
复制
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进行的静态分析,从而导致输出中的错误(在本要点中也是如此),并在捆绑包中创建webpackEmptyContext。这自然不起作用:)

已尝试的选项

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

我看过noParse,但这感觉像是核方法,我不知道潜在的负面副作用可能是什么。

再生码

也是在this gist

index.js:

代码语言:javascript
复制
const sass = require("sass");
console.log(sass);

webpack.config.js:

代码语言:javascript
复制
module.exports = (env) => ({
    entry: "./index.js",
    mode: "development",
    target: "node"
});

package.json:

代码语言:javascript
复制
{
  "devDependencies": {
    "webpack": "^4.34.0",
    "webpack-cli": "^3.3.4"
  },
  "dependencies": {
    "sass": "^1.21.0"
  },
  "scripts": {
    "build": "webpack-cli"
  }
}

目标

我如何配置这个特定模块的上下文,以明确地将readline/fs/chokidar作为依赖项列出,从而可能生成只提供这些值的上下文?

我不介意解决方案有点脆弱,并且需要钉住dart-sass版本。

EN

回答 1

Stack Overflow用户

发布于 2019-06-19 21:50:54

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

sass-prepend-loader.js:

代码语言:javascript
复制
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 (摘录):

代码语言:javascript
复制
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中提取:

代码语言:javascript
复制
/***/ (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\")

希望这是一个暂时的解决方案,我们可以从这些途径中的一个找到更好的解决方案:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56653326

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档