微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我可以从webpack中获得清晰的输出吗?

如何解决我可以从webpack中获得清晰的输出吗?

我想将我的Typescript代码拆分为模块,以实现可维护性,然后将它们合并为浏览器的单个已编译JavaScript文件。 Webpack听起来完全符合我的要求,因为它可以转换我的Typescript,组合模块,并且我可以轻松地进行开发和生产的单独构建任务,选择是否缩小,缓存崩溃,监视文件更改等我也想单独捆绑我的一些模块,以动态加载,这并不难配置。它也可以处理我的CSS,包括从Sass编译。一种工具可以完成所有这些工作?我在哪里注册

但是当我看到webpack创建的JavaScript时,我有些失望。我可以接受它添加到顶部的样板,尽管它比我预期的要多。缩小后的版本实际上不可能重构为可理解的东西,但是可以认为是功能,对吧?

让我感到困扰的是,与源代码相比,开发版本实际上是无法识别的,并且代码是通过庞大的eval丑陋字符串加载的。而且似乎没有将我的任何导出内容添加window对象中,因此我无法从浏览器的控制台访问任何内容。因此,生成代码不仅非常不透明,而且调试起来更加困难(即使使用源映射)。

是否可以通过某种方式对其进行配置,以使调试输出更易于阅读和调试?

这是我用于测试的简单配置:

// ./webpack.config.js

const path = require("path");

module.exports = {
    entry: "./ts/main.ts",output: {
        filename: "[name].js",path: path.resolve(__dirname,"./js")
    },module: {
        rules: [
            {
                use: "ts-loader",exclude: /node_modules/
            }
        ]
    },resolve: {
        extensions: [".ts",".tsx"]
    }
};
// ./tsconfig.json

{
    "compilerOptions": {
        "target": "es5","module": "amd","strict": true,"noUnusedLocals": true,"noUnusedParameters": true,"noImplicitReturns": true,"esModuleInterop": true
    }
}

为了演示,我有一个非常简单的测试文件

// ./ts/main.ts

export function hello(){return "Hello,World!";}

console.log(hello());

我不想将整个输出粘贴到这里,因为要让任何人滚动过去都太多了,所以here it is on JS Bin。但是简单地总结一下,就像这样:

// ./js/main.js

/******/ (function(modules) { // webpackBootstrap
/******/    // The module cache
/******/    var installedModules = {};
/******/
/******/    // The require function
/******/    function __webpack_require__(moduleId) {
// ....... snip 76 lines ....... 
/******/    // Load entry module and return exports
/******/    return __webpack_require__(__webpack_require__.s = "./ts/main.ts");
/******/ })
/************************************************************************/
/******/ ({

/***/ "./ts/main.ts":
/*!********************!*\
  !*** ./ts/main.ts ***!
  \********************/
/*! no static exports found */
/***/ (function(module,exports,__webpack_require__) {

eval("var __WEBPACK_AMD_DEFINE_ARRAY__,__WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__
// ....... snip 223 characters .......
function hello() { return \"Hello,World!\"; }\n    exports.hello = hello;\n    console.log(hello());\n}).apply(exports,__WEBPACK_AMD_DEFINE_ARRAY__),// ....... hey,there's my code! .......
// ....... snip 133 more characters
// //# sourceMappingURL=data:application/json;charset=utf-8;base64
// ....... snip the source map data (gobbledygook that's actually useful)
");

/***/ })

/******/ });

现在,如果我将其嵌入HTML文件并将其加载到浏览器中...

<html>
    <head>
        <script src="js/main.js"></script>
    </head>
</html>

我看到了控制台日志,但无法访问我的功能

JavaScript console

解决方法

webpack生成的捆绑软件并不意味着人类可以检查,至少不能直接检查。在开发中甚至如此。

Webpack有一个devtool option,告诉它输出source maps。这样,即使浏览器执行的代码不同,您也可以在浏览器的调试器中检查看起来像原始源代码的代码。

Webpack代码必须与源代码不同。您可以编写import './foo',但是foo.js不是捆绑软件中的单独文件,它只是捆绑软件中代码的一部分。因此,webpack将import重写为以其他方式工作。

和打字稿的工作原理类似。它支持并非所有浏览器都可能支持的功能,而打字稿编译器会将这些内容转换为大多数浏览器可以处理的内容,有时非常冗长。


最后,这是一个单独的问题:

而且似乎没有将我的任何导出添加到窗口对象

这是设计上的

从文件中导出内容将永远不会添加到全局范围中。这样可以使全局范围保持整洁。如果要在全局范围内放置某些内容,则需要将其明确放置在该位置:

window.foo = { abc: 123 }

但是通常,这里的想法是捆绑中的其他模块可以导入模块并使用它们的代码,而不会出现在全局范围内。

import foo from './foo'

console.log(foo.abc)

现在,如果您的捆绑软件之外有代码,则取决于捆绑软件中显然很棘手的代码,您需要为全局范围显式分配值。但更常见的是,您只需从同样位于同一包中的模块中导入所需的模块,即可使全局范围完全不受污染。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。