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

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 或更复杂的逻辑)来排除那些不适用于前端的代码。然而,这通常不是推荐的做法,因为它可能会引入难以维护的复杂性和潜在的错误。
 类似资料:
  • -或者- 或者我应该以目前相同的模块方式设置它们?我正在尝试,但它总是给我错误,不知道如何在没有类的模块中!

  • vue3 + vite,node版本是18 并且比较奇怪的是同事打的包是正常的,只有我打出来的会这样 怀疑是我电脑的某些配置原因导致的?是一台新电脑,但是找不到原因 有没有大神知道什么原因

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

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

  • 想用vue写一个h5的app,直接用脚手架创建一个空项目,写完之后打包好,在hbuilder中新建一个h5+的空项目,将打包好的dist丢到里面再进行配置打包成apk,这样做能成功?图片.png 无,空想阶段

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