방법: Typescript 모듈에서 CJS 사용

Plasmo에서는 웹 프로젝트에 Typescript를 활용합니다.
humanparser과 같은 CJS 프로젝트에는 다음과 같은 예가 있습니다.

const human = require('humanparser');
const fullName = 'Mr. William R. Hearst, III';
const attrs = human.parseName(fullName);

console.log(attrs);

require 문은 humanparser 모듈을 CJS 코드베이스로 가져오는 방법입니다. 이 문장은 TypeScript/ESM으로 2가지 방식으로 번역될 수 있습니다.

import * as humanParser from 'humanparser'


또는

import humanParser from 'humanparser'


무엇 이니?



답은 humanparser 모듈 자체의 소스 코드에 있습니다. 이것은 ES3-> ES5 -> ES6 이상(현재 ESM)으로 ES가 진화하면서 생성된 아티팩트입니다. 모듈을 내보낼 수 있는 몇 가지 방법이 있습니다.

첫 번째는 ES3에서 ES5로 전환하는 동안(초기 nodejs 시절) 일반적으로 사용되는 항목 기능 또는 객체를 module.exports global에 할당하는 것이었습니다.

module.exports = stuff


이 예제에서는 module.exports 전역을 사용하여 require 문을 연결했습니다. module.exports는 이 모듈에서 내보낸 "모든 것"을 나타내므로 import all 문을 사용해야 합니다.

import * as humanParser from 'humanparser'

*module.exports 개체를 나타냅니다.

ES5->ES6 사이의 전환 중에 발생한 또 다른 방법은 default 속성을 모듈 항목으로 내보내는 것입니다.

module.exports = {
    default : stuff
}


모듈에서 내보낸 stuff 속성에 defaults를 할당했습니다. 이것이 수행된 이유는 ES6에서 다음을 수행하기 때문입니다.

import humanParser from 'humanparser'


위의 코드는 실제로 모듈에서 내보낸default props를 가져오고 있습니다. (ES6의 내보내기 문은 export default stuff )입니다. 위의 가져오기 문은 동등한 CJS 코드에서 다음과 같은 작업을 수행합니다.

const humanParser = require('humanparser').default


이제 humanparser 의 소스 코드로 돌아가서 내보내기 문은 다음과 같습니다.

const parser = module.exports = {};
parser.parseName = function(){}
parser.getFullestName = (str) => {}
parser.parseAddress = (str) => {}


내보낼 소품이 없기 때문에default 파서를 두 가지 방법으로 가져올 수 있습니다. 전체 개체를 가져오는 것입니다.

import * as parser from "humanparser"


또는 별도로 내보낸 소품을 가져옵니다.

import {parseName, parseAddress} from "humanparser"


개인적으로 저는 명명된 내보내기를 가져오는 것을 좋아하고 코드 지능에 도움이 되며 모든 모듈 네임스페이스 가져오기 문제를 처리할 필요가 없습니다.


뒷이야기



정확히 말하자면 2015년 이전으로 돌아가서 angular.js가 여전히 유행하고 react가 여전히 블록의 새로운 아이였고 사람들이 Corodva phonegap을 react native와 비교하고 있었는데 ES3/ES5에서 전환이 있었습니다. commonJS 또는 CJS)를 ES6(ES2015 또는 ESM 또는 MJS - modulejs)로 변환합니다. 확장명을 붙인 사람은 고인이 된 팝 왕의 열렬한 팬이라고 생각합니다.

주의사항



새로운 프로젝트를 보고 계신다면 순수 ESM 모듈에 주의하세요. 다음을 통해서만 가져올 수 있습니다.

import mod from "module-name"


까다로운 부분은 프로젝트도 모듈이어야 한다는 것입니다. 즉, 일반 js(allimport 문을 cjsrequire 호출로 변환)로 컴파일할 수 없습니다. MJS/ecmascript 모듈 파일(.mjs 확장자 포함)이거나 사용자package.json가 모듈 속성을 지정해야 합니다. 그렇지 않으면 단순히 컴파일에 실패하고 ESM 코드가 다음과 같기 때문에 require를 사용하여 가져올 수 없습니다.

export default stuff


대신:

module.exports = stuff


CJS 예에서 module.exports는 다른 모듈에서 가져오기 위해 require 문으로 연결됩니다. 한편, ESM 예제에서 stuffexport 문에 의해 내보내지고 있으므로 import 문을 통해서만 가져올 수 있습니다.

여기서 딜레마는 TypeScript를 사용 중이고 ESM 전용 모듈과 잘 작동하기를 희망하는 경우 신맛이 나는 사탕을 먹고 있다는 것입니다. 그렇지 않습니다. Typescript 컴파일러는 가져온 모듈이 ESM인지 아닌지 아직 신경 쓰지 않습니다. 제대로 구성하지 않으면 모두 CJS 가져오기로 변환합니다. 또한 컴파일된 코드를 실행할 때 nodejs에게 실험적 플래그를 사용하도록 지시해야 합니다. https://nodejs.org/api/esm.html#customizing-esm-specifier-resolution-algorithm

P.s: 이 게시물은 뇌 덤프입니다. 유용하시다면 천만에요. 그렇지 않은 경우 읽을 수 없는 이 게시물에 대한 MIT 라이선스는 다음과 같습니다.

Copyright 2022 L❤☮🤚

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

좋은 웹페이지 즐겨찾기