1

我正在尝试从 Typescript 源构建一个 React JS 应用程序,使用 Bazel 构建并使用 Webpack 作为捆绑器。rules_nodejs 包括examples/react_webpack,它展示了如何使用ts_project,但我需要使用它来构建它,ts_library因为ts_project生成的 TS 文件(在我的例子中是 protobuf TS 文件)似乎效果不佳。

我如何才能更好ts_library地使用 Webpack(反之亦然)?

是我尝试调整 examples/react_webpack 以使用ts_library而不是ts_project. 它使用 Webpack 4,因为这就是示例所使用的,我想尽量减少更改。为了完整起见,我也有这个提交,它重现了 Webpack 5 的更改,尽管这是我第一次使用 Webpack 5,所以我可能会在迁移中引入其他问题。

当我bazel run server使用 Webpack 4 提交运行,然后在 Chrome 中加载结果页面时,我在控制台上收到此错误:

app.bundle.js:6 Uncaught Error: Cannot find module 'react'
    at n (app.bundle.js:6)
    at app.bundle.js:6
    at app.bundle.js:6
    at Object.<anonymous> (app.bundle.js:6)
    at n (app.bundle.js:1)
    at app.bundle.js:1
    at app.bundle.js:1

Webpack 5 发出了类似的错误,但信息量稍大一些(?):

_sync:2 Uncaught Error: Cannot find module 'react'
    at webpackEmptyContext (_sync:2)
    at eval (index.tsx:7)
    at eval (index.js:3)
    at eval (index.js:12)
    at Object../bazel-out/k8-fastbuild/bin/index.js (main.js:18)
    at __webpack_require__ (main.js:172)
    at main.js:188
    at main.js:189

在这两种情况下,我都点击了 webpack require for ./bazel-out/k8-fastbuild/bin/index.js,这是我指定的入口点(不确定这是否是指定为入口点的正确路径)。这导致我进入index.jsAMD(?) 模块,然后需要./bazel-out/k8-fastbuild/bin sync recursive. 该要求似乎直接导致错误:

/***/ "./bazel-out/k8-fastbuild/bin sync recursive":
/*!******************************************!*\
  !*** ./bazel-out/k8-fastbuild/bin/ sync ***!
  \******************************************/
/***/ ((module) => {

eval("function webpackEmptyContext(req) {\n\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\te.code = 'MODULE_NOT_FOUND';\n\tthrow e;\n}\nwebpackEmptyContext.keys = () => [];\nwebpackEmptyContext.resolve = webpackEmptyContext;\nwebpackEmptyContext.id = \"./bazel-out/k8-fastbuild/bin sync recursive\";\nmodule.exports = webpackEmptyContext;\n\n//# sourceURL=webpack:///./bazel-out/k8-fastbuild/bin/_sync?");

我注意到的另一件事:

rules_nodejs 示例/react_webpack 示例,使用ts_project,编译index.tsx如下:

"use strict";
exports.__esModule = true;
var React = require("react");
var ReactDOM = require("react-dom");
var styles = require("./styles.css");
ReactDOM.render(React.createElement("h1", { className: styles.h1 }, "Hello, world!"), document.getElementById("root"));
s

我认为这是一个脚本?

ts_library像这样编译它,我认为这是一个模块?

(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define("react_webpack/index", ["require", "exports", "react", "react-dom"], factory);
    }
})(function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    const React = require("react");
    const ReactDOM = require("react-dom");
    ReactDOM.render(React.createElement("h1", null, "Hello, world!"), document.getElementById("root"));
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9pbmRleC50c3giXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7SUFBQSwrQkFBK0I7SUFDL0Isc0NBQXNDO0lBRXRDLFFBQVEsQ0FBQyxNQUFNLENBQ2IsZ0RBQXNCLEVBQ3RCLFFBQVEsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQ2hDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCAqIGFzIFJlYWN0RE9NIGZyb20gXCJyZWFjdC1kb21cIjtcblxuUmVhY3RET00ucmVuZGVyKFxuICA8aDE+SGVsbG8sIHdvcmxkITwvaDE+LFxuICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInJvb3RcIilcbik7XG4iXX0=

这种差异是问题的根源吗?我是否应该试图弄清楚为什么/如何ts_project使用更简单的形式,然后说服ts_library做同样的事情?还是告诉 Webpack 按原样捆绑ts_library输出更好?如果是后者,怎么做?

编辑:ts_library规则似乎使用了自己设计的 tsconfig 设置compilerOptions.moduleumd. ts_project在版本中设置相同的选项会导致index.js上面显示的所有出厂设置增加。

4

1 回答 1

2

看起来问题在于它的参数ts_library默认为. Webpack,至少在 rules_nodejs 示例中配置(即没有特定于 UMD 的插件)似乎无法处理由. 改成解决问题。我不知道这是否是最好的解决方案,但它会导致 Webpack 创建一个功能性捆绑的 JS 文件。devmode_moduleumdts_librarydevmode_modulees2015

于 2021-01-06T19:14:13.890 回答