当前位置: 首页 > 知识库问答 >
问题:

javascript - 请问是否是在typescript项目编写的时候使用了nodejs的fs模块,那么打包dist为esm模块之后,就实际不能在前端使用(比如:react/vue使用这个打包后的库)?

吕钧
2024-08-29

在使用TypeScript 开发一个项目的时候:
1、我们是可以既使用import 引入三方库,也可以使用require引入三方库是吗?

1)这个是否是叫做esm和cjs的模块化引入?
2)import和require是否可以一起在项目中使用?
3)是需要在哪里配置什么才能使用吗?

2、然后在build的时候,打包到dist内,可以打包esm,也可以打包cjs是吗?
1)请问是否是在typescript项目编写的时候使用了nodejs的fs模块,那么打包dist为esm模块之后,就实际不能在前端使用(比如:react/vue使用这个打包后的库)?

共有3个答案

东方和煦
2024-08-29

一般来说,在使用TypeScript开发项目的时候,会通过2个构建步骤,

一、 通过tsc进行编译,将ts代码转换成js代码
二、 通过webpack等进行编译,将js代码中的模块化引入转换成浏览器能识别方式,但如果你的项目是为了在nodejs中运行的,可能就不需要这一步

    1. Q: 对于任意一个三方库,是否能随意使用import/require进行引入
      A: 准确的答案是不能,但是,

      • 考虑到三方库在构建发布的过程中,可能会使用构建工具添加如下代码,这样,你就能随意使用import/require对这个第三方库进行引入了

        // 代码内容
        const myFunction = () => {
          console.log('This is a function');
        };
        
        // 检测当前环境并导出
        if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
          // CommonJS 导出
          module.exports = {
              myFunction
          };
        } else {
          // ES Module 导出
          export { myFunction };
        }
  • 1.1 Q: 这个是否是叫做esm和cjs的模块化引入?
    A:

     - `reuire('path/to/module')` 属于 CommonJS 模块规范。
     - `import some module from 'path/to/module'` 属于 ES Module 模块规范。
    
  • 1.2 Q: import和require是否可以一起在项目中使用?
    A: 可以,但是不建议,因为会导致代码风格混乱
  • 1.3 Q: 是需要在哪里配置什么才能使用吗?
    A: 在 tsconfig.json 文件中设置以下选项,以下选项会将import/require构建成js代码时,变成CommonJS模块规范

      {
         "compilerOptions": {
             "module": "commonjs",
             "esModuleInterop": true,
             "allowSyntheticDefaultImports": true
         }
      }

    1. Q: 在build的时候,打包到dist内,可以打包esm,也可以打包cjs是吗?
      A: 可以,看你的构建选项,CommonJS模块规范已经在上面例举了,下面例举ES Module 模块规范

      • tsconfig.json

          {
            "compilerOptions": {
                "module": "ESNext", 
                "target": "ESNext", 
                "esModuleInterop": true, 
                "moduleResolution": "node" 
            }
          }
      • webpack配置方式

          webpack({
            output: {
                libraryTarget: 'commonjs2', // 指定输出为 CommonJS 规范
                library: {
                    type: 'module', // 指定输出为 ES Module 规范
                }
            }
          })
  • 2.1 Q: 请问是否是在typescript项目编写的时候使用了nodejs的fs模块,那么打包dist为esm模块之后,就实际不能在前端使用
    A: 使用CommonJS 规范和ES Module 规范构建项目无法决定这个代码是否能在nodejs/浏览器中运行,

     决定代码是否能在nodejs/浏览器运行的本质是在于你使用的api是否支持在对应的运行环境中使用,
     如,nodejs的fs模块中,`fs.readFile`在浏览器中根本不支持,
     如,docuemnt在nodejs中,根本没这个对象,
     至于因为`CommonJS 规范`或`ES Module 规范`导致在浏览器中报错的问题,
     可以使用`webpack`等构建工具,转换成浏览器能识别的形式
谢诚
2024-08-29

Javascript 中第三方库有两种类型,分别是 ES Module 和 CommonJS Module。

  1. ESM 需要通过 import 导入,而 CJS 需要通过 require 导入。使用那种方式导入取决于库打包后产物的类型,一般第三方库两种类型的产物都提供。
  2. import 和 require 可以一起使用,但是需要打包工具的额外处理,而且不推荐这样做。一般统一使用 import。
  3. 这取决于你使用的打包工具(Webpack、Vite 等)。一般情况下,这些打包工具是开箱即用的,你无需考虑这些问题。

  1. 是的,你可以选择打包为 ESM 或是 CJS,一般情况下,如果你在开发第三方库的话,会选择同时提供两种类型的产物。
  2. 是的,在前端(浏览器)中你无法使用 NodeJS 的模块,例如 fs
麻华辉
2024-08-29

回答问题

1. TypeScript 项目中的模块引入

  1. 是否可以既使用 import 又使用 require 引入三方库?

    • 是的,TypeScript 支持 ES Modules (import) 和 CommonJS (require) 两种模块系统。这取决于你的项目配置(如 tsconfig.json 中的 module 字段)以及打包工具(如 Webpack, Rollup, TypeScript 自身的编译等)的配置。
  2. 这个是否叫做 ESM 和 CJS 的模块化引入?

    • 是的,import 通常指的是 ECMAScript Modules (ESM),而 require 则是 CommonJS Modules (CJS) 的引入方式。
  3. importrequire 是否可以一起在项目中使用?

    • 理论上可以,但通常不推荐这样做,因为它可能会使项目的模块系统变得混乱。通常,你会选择一种模块系统(ESM 或 CJS)并在整个项目中保持一致。
  4. 需要在哪里配置什么才能使用?

    • 这通常取决于你的构建工具(如 Webpack, Rollup 等)和 TypeScript 编译器(通过 tsconfig.json)。例如,在 tsconfig.json 中设置 "module": "esnext""module": "commonjs" 可以控制 TypeScript 编译器的行为。构建工具的配置则决定了最终打包文件的模块系统。

2. 打包到 dist 目录

  1. 是否可以打包为 ESM 和 CJS?

    • 是的,大多数现代打包工具(如 Rollup, Webpack, TypeScript 的 tsc 命令配合适当的插件或配置)都支持同时生成 ESM 和 CJS 格式的包。
  2. 在 TypeScript 项目中使用 Node.js 的 fs 模块后,打包为 ESM 模块是否不能在前端使用?

    • 是的,如果你在 TypeScript 项目中使用了 Node.js 的 fs 模块(或其他任何 Node.js 特有的模块),并且将这个库打包为 ESM 格式,那么它通常不能在前端环境(如 React 或 Vue 应用)中直接使用,因为这些环境不支持 Node.js 的核心模块。
    • 如果你需要在前端项目中使用与文件系统交互的功能,你可能需要寻找或编写一个适用于浏览器的替代方案(如使用 IndexedDB, localStorage, 或者通过后端 API 进行文件操作)。
    • 如果你确实需要在前端项目中包含这个库,并且它依赖于 Node.js 的 fs 模块,你可能需要创建一个仅包含前端可用部分的版本,或者使用条件编译(如 TypeScript 的 // @ts-ignore 或更复杂的逻辑)来排除那些不适用于前端的代码。然而,这通常不是推荐的做法,因为它可能会引入难以维护的复杂性和潜在的错误。
 类似资料:
  • -或者- 或者我应该以目前相同的模块方式设置它们?我正在尝试,但它总是给我错误,不知道如何在没有类的模块中!

  • 现在有一个需求是需要动态的创建vue文件,并写入内容放到指定目录下,动态创建文件打算使用node的fs模块,但是使用fs模块的writeFile会报 is not a function 是为什么呢

  • 我试图找到问题的解决方案,但找不到,正在寻找一些“最佳实践范例”。我有一个nodejs express应用程序,我的函数被拆分成文件。例如,我有一个控制器(oktacontroller.js): 在两个导出的函数(都是快速路由)中,我都需要var-okta_-api_键。我知道我可以通过在这两个函数中查询它们来获得它们,因为它们是异步函数,我可以在那里使用wait,但是每次查询都感觉很愚蠢(因为它

  • 请问通过webpack打包为esm包,npm link后包空对象,请问是怎么回事?导出的包有编译,npm link后得到的是{}对象 两个文件metab.ts: 入口文件metas.ts引入metab.ts: 这样打包后npm link,在其他项目里导入metas.ts,得到是一个空对象{},如果我把metas.ts去掉import,直接写上值可以得到结果 请问不能import是怎么回事呢?我的w

  • 我正在为客户端javascript代码制作一个typescript项目。 在我使用打字稿之前,我导入了一个这样的模块(这是 es6 中的香草 js) < code > import * as THREE from ' https://THREE js . org/build/THREE . module . js '; 但是使用打字稿,我用 安装了模块,然后像这样导入它 < code > impo

  • 原本本地创建的项目,都可以正常打开的,今天把它复制到了svn的文件夹中,并commit上去了,然后重新用vscode打开,npm i 了项目,但是每个文件中都有这种波浪线说找不到模块,请问有没有人知道什么原因的?

  • 问题内容: 因此,另一个问题(如何使用打字稿 导入 模块)的一般答案是: 1)创建blah.d.ts定义文件。 2)使用: 至关重要的是,您需要 在 node_modules中的某个位置加载文件foo.d.ts和foo.js; 并且 NAME foo必须与两者 完全 匹配。现在… 我想回答的问题是如何 编写 一个可以以这种方式导入的打字稿模块? 可以说我有一个像这样的模块: 我想从base.ts中

  • 我使用的是sbt 0.13.8和xsbt-web-plugin 2.0.3 我有一个多模块sbt项目。打包时,其中一个模块应该是war文件的形式。所有其他的都在jar文件中。 当我添加xsbt-web插件时,打包会为所有模块生成jar和war。如何告诉xsbt-web插件仅将自身应用于应该打包为war的模块? 我已经找到了一个解决方案,那就是为每个非战争模块修改packagedArtifacts列