如何为库设置 TypeScript 编译器,以便 Webpack 在依赖项目中删除未使用的模块?

2023-11-26

主题库初步说明

很抱歉占用您的时间让您阅读本文。我写它是为了回答诸如“你在做什么?”之类的问题。和“你为什么要这样做?”。

The library由大量辅助函数和类组成。在这方面它与 lodash 类似(检查lodash的结构),但与 lodash 不同的是,源代码的组织方式是多级目录。这对开发人员来说很舒服,但对用户来说可能不太舒服:要将所需的功能导入到项目中,用户必须知道它在哪里,例如。 G。:

import { 
  computeFirstItemNumberForSpecificPaginationPage
} from "@yamato-daiwa/es-extensions/Number/Pagination";

为了解决这个问题,大部分功能已导入到index.ts并从那里再次出口。现在用户可以获得所需的功能:

import { 
  computeFirstItemNumberForSpecificPaginationPage 
} from "@yamato-daiwa/es-extensions";

请注意,所有功能index.ts(将由 TypeScript 编译为index.js) 适用于 BrowserJS 和 NodeJS。特别适用于 BrowserJS 的功能位于BrowserJS.ts特别是对于 NodeJS 来说NodeJS.ts(目前几乎是空的,但再出口方法是相同的)。

另外,在这个问题得到解决之前,我将编译后的 JavaScript 包含到库存储库中(Distributable目录).

Problem

从现在开始,@yamato-daiwa/es-extensions 是library任何依赖它的项目都是消耗项目.

我预计消费项目的所有未使用的函数/类将被切断Webpack 优化。例如,在下面的情况下我期望isUndefinedWebpack 包中仅保留函数:

import { isUndefined } from "@yamato-daiwa/es-extensions"

const test: string | undefined = "ALPHA";
console.log(isUndefined(test));

但实际上,Webpack 留下了一切index.js图书馆的。我美化了 Webpack 构建的缩小版 JavaScript;它像是:

(() => {
    "use strict";
    var e = {
            5272: (e, t) => {
                Object.defineProperty(t, "__esModule", {
                    value: !0
                }), t.default = function(e, t) {
                    for (const [a, n] of e.entries())
                        if (t(n)) return a;
                    return null
                }
            },
            7684: (e, t) => {
                Object.defineProperty(t, "__esModule", {
                    value: !0
                }), t.default = function(e, t) {
                    const a = [];
                    return e.forEach(((e, n) => {
                        t(e) && a.push(n)
                    })), a
                }
            },
  // ...

我想每个人都明白这是不可接受的,特别是对于每千字节都很重要的浏览器应用程序。

如何解决这个问题呢?理想的解决方案(如果存在)不会触及源文件组织,只需更改 TypeScript 配置。

Repro

我创建又一个存储库(重现)您可以在其中尝试上面的示例。

实验流程

  1. 通过 VCS 获取此存储库
  2. 一如既往地安装依赖项(npm i命令)。
  3. 检查src/index.ts。它进口isUndefined从库中获取函数并使用它。
  4. Run npm run ProductionBuild
  5. 美化输出index.js通过类似工具美容师io。您将看到整个库已被捆绑,而只需要inUndefined已被捆绑。

关于原因的思考

第一个候选原因是使用 reexportint 模式,确切地说来源/index.ts, 来源/BrowserJS.ts and 来源/NodeJS。编译出来的index.js好像:

const isStringifiedNonNegativeIntegerOfRegularNotation_1 = require("./Numbers/isStringifiedNonNegativeIntegerOfRegularNotation");
exports.isStringifiedNonNegativeIntegerOfRegularNotation = isStringifiedNonNegativeIntegerOfRegularNotation_1.default;
const separateEach3DigitsGroupWithComma_1 = require("./Numbers/separateEach3DigitsGroupWithComma");
exports.separateEach3DigitsGroupWithComma = separateEach3DigitsGroupWithComma_1.default;

(检查完整文件)

如果要从其单独的模块导入每个函数,例如import isUndefined from "@yamato-daiwa/es-extensions/TypeGuards/isUndefined"代替import { isUndefined } from "@yamato-daiwa/es-extensions",不会输出多余的代码。但正如我已经说过的,这个解决方案是不可接受的,因为图书馆用户必须知道在哪里isUndefined并组织了其他功能。

另一个原因可能是输出模块类型。目前它是一个CommonJS。这里是tsconfig.json图书馆的:

{
  "compilerOptions": {

    "target": "ES2020",
    "module": "CommonJS",
    "moduleResolution": "Node",

    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,

    "removeComments": true,

    "outDir": "Distributable/",
    "declaration": true
  },

  "include": [ "Source/**/*" ]
}

根据假设,根据特定的模块类型,Webpack 可以将代码捆绑到整体结构中,即使这些模块尚未使用,也无法分解和过滤掉某些模块。

现在所有这些(AMD、UMD、CommonJS)慢慢成为历史的一部分, 但我们仍然可以在旧脚本中找到它们。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何为库设置 TypeScript 编译器,以便 Webpack 在依赖项目中删除未使用的模块? 的相关文章

  • 如何使用画布调整图像大小然后裁剪图像

    我已经知道如何 gt 调整图像大小 var image document getElementById myImage canvas document createElement canvas ctx canvas getContext 2
  • 停止 ASP.NET 按钮的页面重新加载

    NET 应用程序中 我插入了一个调用 Javascript 函数的按钮 OnClientClick事件 和 VB NET 函数 OnClick event
  • Typescript 中未定义的 d3.scale

    我是 Typescript 的新手 2 周 我正在从事包装 d3 js 框架的项目 我在使用 d3 d ts 命名空间 导出模块 导入时遇到问题 我的问题 当我尝试使用 d3 scale linear 时 浏览器控制台中出现错误 TypeE
  • 添加滚动到顶部按钮(Ionic 2 | Typescript)

    大家好 我正在尝试添加 滚动到顶部按钮 实现以下内容 1 当用户向下滚动时显示按钮 2 当用户向上滚动时隐藏按钮 3 如果点击该按钮 则滚动到顶部并隐藏该按钮 关于如何使其正确的任何建议 多谢 简化scrollToTop from adri
  • 使用 Sequelize 连接多个联结表

    我有一个包含三个主表的数据库 users teams and folders由两个连接表连接 users teams and teams folders 用户和团队之间以及团队和文件夹之间存在多对多关系 一个用户可以属于多个团队 并且团队可
  • 浏览器中的javascript:异步任务执行模型

    我正在尝试集中注意力并了解 javascript 异步在单线程浏览器环境中的工作原理 作为异步 我们可以同时处理计时器和 xhr 请求 现在假设我有类似下面的东西 function doStuff for var i 0 i lt 1000
  • AngularJS:如何缓存从 $http 调用返回的 json 数据?

    如何缓存从 http 调用返回的 json 数据 我使用以下风格的 http 调用 http url SomeWebMethodUrl method POST data query somevalue headers Content Typ
  • 根据路由动态加载 Node.js 模块

    我正在使用 Express 在 Node js 中做一个项目 这是我的目录结构 root start js server js lib api user getDetails js user register js The lib api
  • Javascript 搜索并替换包含方括号的字符序列

    我正在尝试在字符串 Nationality EN ESP 中搜索 EN 我想从字符串中删除它 所以我使用替换方法 代码示例如下 var str Nationality EN ESP var find EN var regex new Reg
  • Mongo JSON 文档 -> JSON -> BSON

    我正在使用 Node js 构建一个使用 mongodb 的 Web 套接字服务器 我使用 node mongodb native 作为访问 mongodb 的库 当我对数据库中的对象调用 console log sys inspect i
  • Mustache.js 只允许换行,转义其他 HTML

    我正在根据用户输入创建评论 并在用户单击 提交 后使用 Mustache js 渲染它们 我意识到我可以替换用户输入换行符 n with br 呈现为 HTML 中断 例如 myString replace n g br 我意识到我可以使用
  • 即使我的目标是 ES3,TypeScript 输出仍然使用 Array.prototype.reduce

    我在玩了一下 TypeScript 并发现了一些奇怪的地方 假设我正在构建一个小应用程序 遗憾的是 也需要支持 IE8 所以我将 TypeScript 编译器设置为目标 ES3 我以为我可以安全地使用 ECMAScript 5 1 的好东西
  • 如何在 html5 中加载部分 html? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 询问我们的问题推荐或查找工具 库或最喜欢的场外资源与 Stack Overflow 无关 因为它们往往会吸引固执己见的答案和垃圾邮件 反而
  • 样式表何时添加到 document.styleSheets

    我正在尝试使用 javascript 动态添加 css 样式表规则 例如示例 2here https developer mozilla org en DOM CSSStyleSheet insertRule 它在大多数情况下都有效 但似乎
  • Svg 点击事件无法正常工作

    我试图让我的 SVG 看起来像一个 饼形 看起来一切都很好 此外 我希望它们每个都有不同的点击事件 function one alert 1 function two alert 2 function three alert 3 funct
  • 在 for 循环中突破 Promise 块

    我有以下代码 this storeNameValidate function stores var deferred q defer console log stores for storeIndex in stores this name
  • Select2 触发器(“更改”)创建无限循环

    假设页面上有两个 select2 元素 都使用 onChange 为了以编程方式在一个 select2 元素中设置一个值 您可以使用 id1 val xyz trigger change 如果您在这两个元素之一中进行选择时想要将另一个元素重
  • Rxjs 带延迟功能的重试

    我正在尝试使用retry with delay函数 我预计函数会在 1000 毫秒延迟后调用 但事实并非如此 这里可能会出现什么错误 查看控制台输出 同一时间 16 22 48 我预计有 16 22 48 16 22 59 canCreat
  • 返回语句后的声明

    function f return f1 function f1 return 5 f returns 5 为什么这有效 之后声明局部函数有什么好处return 这是好的做法吗 它之所以有效 是因为函数声明都是由解释器在第一次传递时评估的
  • 未终止的字符串文字

    我有一个 php 脚本 可以在我的服务器上上传 mp3 文件 我使用 上传 有一个事件 onSelect 文档 http www uploadify com documentation events onselect 当文件上传时调用 使用

随机推荐

  • 在 Node.js 中读取文件

    我对在 Node js 中读取文件感到非常困惑 fs open start html r function err fileToRead if err fs readFile fileToRead encoding utf 8 functi
  • 如何计算以GPS坐标为中心的地球上的圆上的点?

    在 KML 中画一个圆 如何获取地球上某个点的 GPS 坐标 例如以十进制格式 并生成近似于以该点为中心的圆的多边形的坐标 具有 20 多个数据点的多边形看起来像一个圆形 数据点越多 圆就越好看 我正在编写一个生成 KML 的程序 但不知道
  • 从字节数组创建私钥

    有没有办法从字节数组生成私钥 我使用 getEncoded 方法获取了这个字节数组 但现在我必须将其转换回 PrivateKey 谢谢 武克 我也在寻找这个答案 终于找到了 keyBytes 是最初使用 getEncoded 创建的字节数组
  • 在 Java FX 工作线程中不断更新 UI

    I have Label label在我的 FXML 应用程序中 我希望这个标签每秒改变一次 目前我使用这个 Task task new Task
  • 根据引用者限制对AWS S3存储桶的访问

    我试图限制对 S3 存储桶的访问 并仅允许基于引用来源的列表中的某些域 存储桶策略基本上是 Version 2012 10 17 Id http referer domain lock Statement Sid Allow get req
  • Sphinx LaTeX 标记限制

    我正在尝试在 Sphinx 版本 1 1 2 1 的多行数学模式中做三件非常基本的事情 即使在数学模式下 也将下划线写入变量名称的一部分 Use the big biggl等 构成大括号和圆括号的分隔符 并包括常规文本作为方程的一部分 请注
  • 从远程通知打开 ViewController

    当我的应用程序捕获远程通知时 我想打开 ViewController 当我收到通知时 我想打开一个 SimplePostViewController 所以这是我的 appDelegate var window UIWindow var na
  • spring data r2dbc可以生成schema吗?

    我正在使用 R2DBC 和 H2 创建一个快速项目 以熟悉这种新的反应性东西 制作了一个扩展 ReactiveCrudRepository 的存储库 只要我使用 DatabaseClient 发出与我的实体首先匹配的 CREATE TABL
  • 跨多个区域的 AppEngine 负载均衡

    据我所知 AppEngine 项目仅定义为一个区域 Google 会自动为您处理负载平衡 但是 如果我在世界各地的不同地区有应用程序 在不同的项目中 因为这似乎是一个要求 那么我如何使用 Google Cloud 中的 HTTPS 负载均衡
  • 保存 matplotlib python 函数生成的图

    我创建了一个函数 它从数据集中获取一系列值并输出一个图 例如 my plot location dataset min temperature max temperature 将返回函数中指定温度范围内的降水图 假设我想保存加利福尼亚州 6
  • Jquery UI 选项卡:关闭选项卡时如何隐藏选项卡及其相应的 div

    我使用了 Jquery UI 选项卡 并为选项卡提供了关闭选项 默认情况下 我创建三个选项卡及其相应的三个 div 现在 当我关闭选项卡时 选项卡及其 div 将被删除 我需要隐藏选项卡和 div 当我单击 添加选项卡 时 我应该只显示隐藏
  • 创建 shell 脚本以在 Linux 上运行 Java 程序

    我创建了一个同步两个目录内容的java程序 该程序将两个目录的位置作为参数来同步它们 同步信息存储在每个目录内的 JSON 格式文件中 我有一个参考库json simple 1 1 1 jar 我在 Windows 上从 Eclipse 运
  • 带括号和不带括号的方法调用的优先级是什么?

    以前的答案 The answer到类似的question是错的 Ruby 中都没有提到方法调用文档也不在社区维基 不带括号的方法调用 比 高or or似乎比不带括号的方法调用具有较低的优先级 puts false or true 相当于 p
  • 如何使用 async/await 返回 Ajax 结果? [复制]

    这个问题在这里已经有答案了 试图熟悉async await 我在 Chrome 中尝试了以下代码 async function f return await get var result f but result不保存结果 字符串 相反 它
  • 在 R 包中包含命令行脚本

    我有兴趣为我正在编写的名为 Slidify 的 R 包提供命令行界面 它用Rscript我认为这将使其成为跨平台的 脚本存储在子目录中inst slidify 为了从任何目录使用该脚本 我将其路径添加到我的 bash profile就像我在
  • 与特定用户以只读方式共享 GitHub 上的私有 git 存储库

    我终于想学习如何 git 所以我正在 GitHub 上写一篇关于版本控制的相当广泛的论文 我有一个freeGitHub pro 帐户 感谢我的大学 所以我可以添加私人存储库 我需要添加我的主管 以便他可以访问这些文档 但我希望他的 GitH
  • 方法名称是否会编译到 EXE 中?

    做类 方法和变量姓名包含在邮件中将 Windows 应用程序项目编译成 EXE 后 For 混淆 名称越少 逆向工程就越困难 And for 表现 名称更短 访问速度更快 e g 因此 如果方法是通过名称调用的 保留名字short 更好的命
  • 是否可以在控制器内获取当前的 Unity 容器

    我像这样注册了统一容器 var container new UnityContainer container RegisterType
  • 在 Node.js 中管理会话? [关闭]

    Closed 这个问题是基于意见的 目前不接受答案 在 Node js 中管理会话变量的最佳方法是什么 有图书馆吗 您可以使用以下方法轻松做到这一点 连接 http senchalabs github com connect Connect
  • 如何为库设置 TypeScript 编译器,以便 Webpack 在依赖项目中删除未使用的模块?

    主题库初步说明 很抱歉占用您的时间让您阅读本文 我写它是为了回答诸如 你在做什么 之类的问题 和 你为什么要这样做 The library由大量辅助函数和类组成 在这方面它与 lodash 类似 检查lodash的结构 但与 lodash
Powered by Hwhale