My goal is to create a React component library with TypeScript. I have configured webpack to bundle my components and everything works as expected until I create a folder, that is outside the scope of the entry and which includes TypeScript files.
I have simplified the config as much as possible and I can still reproduce the problem.
webpack.config.js
const path = require('path');
const jsConfig = {
entry: './src/components/index.ts',
module: {
rules: [
{
test: /\.ts(x?)?$/,
exclude: /node_modules/,
use: {
loader: 'awesome-typescript-loader'
}
}
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
libraryTarget: 'commonjs2',
pathinfo: true
},
resolve: {
extensions: ['.ts', '.tsx', '.js']
},
externals: {
react: 'react',
'react-dom': 'react-dom'
},
optimization: {
minimize: false,
usedExports: true,
sideEffects: false
},
mode: 'production'
}
const configuration = [jsConfig];
module.exports = configuration;
tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"jsx": "react",
"target": "es5",
"lib": [
"es2015",
"dom"
],
"outDir": "dist",
"sourceMap": false,
"declaration": true,
"moduleResolution": "node"
}
}
Here is the initial folder structure:
|-- node_modules
|-- src
| `-- components
| |-- Button
| | `-- Button.tsx // Example component
| `-- index.ts // A file that exports all components
|-- package.json
|-- tsconfig.json
`-- webpack.config.js
When I run webpack, it creates a dist folder with the following structure:
-- dist
|-- Alert
| `-- Alert.d.ts
|-- index.d.ts
`-- index.js
This is what I'm trying to achieve. However, I want to add, let's say, a helper function, and create a folder called helpers in src. Then I add a simple helper.ts file and just add a function that logs something on the console. I'm not exporting anything and I haven't invoked the helper function yet. So if I run webpack now, the dist will look like this:
-- dist
|-- components
| |-- Alert
| | `-- Alert.d.ts
| `-- index.d.ts
`-- index.js
I suppose there is something essential, that I'm missing in understanding webpack's workflow. Why does this components folder emerge in the build output? Notice that it also wraps the index.d.ts - definitely not what I'm going for.
Thanks in advance!
After a few days on this issue, I think I've found the answer. I will describe my steps to fixing the problem:
I realised that if the
helperfile is not with TypeScript extension, the build output does not change.I replaced
awesome-typescript-loaderwithts-loader- the results were the same, the output folder structure changes depending on whether thehelperis a TypeScript file or not. Moreover, I didn't find any configuration options for the loader, which would solve the issue.I had to pay more attention on the fact that both loaders I tried make use of the
tsconfig.json. The docs show that I can set thefilesorinclude/excludeproperties of the configuration object, which will affect the end result of compilation. Here is the answer to the question why unused files are compiled:One more thing to add, since I mentioned the location of
index.d.tsin the output folder structure: My goal forhelper.tswas to use it in the components, of course. Therefore I had to accept that with the current configuration, my output folder structure changes, because the helper file had be transpiled. This caused the type definition file to end in thecomponentsfolder. I simply moved theindex.ts(which exports the components) one level above - insrcand updated the webpack entry file.I hope this helps someone.