typescript 파일을 es5로 번들링하기 위해서 webpack을 사용하였습니다.
webpack 번들링은 성공하였는데, package를 다른 프로젝트에서 import하니까 빈 object만 출력되었습니다.
webpack version 정보
"devDependencies": {
"@webpack-cli/generators": "^2.4.2",
"ts-loader": "^9.3.0",
"typescript": "^4.7.3",
"webpack": "^5.73.0",
"webpack-cli": "^4.9.2"
},
output파일인 bundle.js를 보니 __webpack_unused_exports__
로 빠져있었습니다. (아래는 bundle.js의 일부분입니다.)
__webpack_unused_export__ = ({ value: true });
__webpack_unused_export__ = void 0;
var create_pr_1 = __webpack_require__(218);
__webpack_unused_export__ = create_pr_1.default;
libraryTarget: 'commonjs2'
를 webpack.config.js에 넣어보니 bundle.js에서 exports가 제대로 되었습니다. (아래와 같이 바뀌었습니다. 관련문서)
exports.pr_createPR = void 0;
var create_pr_1 = __webpack_require__(218);
exports.pr_createPR = create_pr_1.default;
또 다른 문제가 발생했는데, import되는 결과물이 아래와 같이 default property로 출력되었습니다. 아래와 같이 된다면 import한 파일에서 다시 default로 들어가야 createPR이라는 함수를 사용할 수 있는 상황이 되었습니다.
// 새로운 프로젝트에서 위 package를 import하는 경우
import script from '@devstefancho/github-script'
console.log(script);
// node index.js의 결과 --> { default: { createPR: [Function (anonymous)] } }
찾아보니 아래와 같이 library 이름을 추가하라는 문서가 있었습니다.
module.exports = {
output: {
library: {
name: 'MyLibrary',
type: 'var',
export: 'default',
},
},
};
적용해보니 아래와 같이 그냥 default 이름을 원하는대로 바꾸는 것이었습니다.
{ MyLibrary: { createPR: [Function (anonymous)] } }
이것은 제가 원하는 방식이 아니었습니다.
몇번 더 테스트후에 알게 된 것인데, webpack에서는 이제 export default은 지원하지 않는것 같았습니다. 좀 더 정확히 표현하자면 export default는 bundle.js에서 default라는 property를 생성하여 값이 할당되는 것 같습니다. (관련 문서는 찾지 못했습니다.)
// @devstefancho/github-package의 index.ts 에서 named export를 하였음
export { createPR } from './create-pr';
위와 같이 export를 하였더니, 원하는대로 import를 할 수 있게 되었습니다.(아래는 import 결과 입니다.)
// 새로운 프로젝트에서 위 package를 import하는 경우
import script from '@devstefancho/github-script'
console.log(script);
// node index.js의 결과 --> { pr_createPR: [Function (anonymous)] }
webpack.config.js의 결과물은 아래와 같습니다.
const path = require('path');
module.exports = {
entry: './src/index.ts',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
libraryTarget: 'commonjs2', // 이걸 꼭 써줘야합니다.
},
optimization: {
minimize: false,
},
};
tsconfig.json
{
"compilerOptions": {
"outDir": "./dist/",
"sourceMap": true,
"noImplicitAny": true,
"module": "commonjs",
"target": "es5",
"jsx": "react",
"allowJs": true,
"moduleResolution": "node"
}
}