Question
I am building a UI components library to reuse in my projects. The library is written in TypeScript and .less with React, and built with WebPack.
.
├── README.md
├── dist
├── index.js
├── package-lock.json
├── package.json
├── src
│ ├── Span
│ │ ├── Span.less
│ │ └── index.tsx
│ └── Tag
│ ├── Tag.less
│ └── index.tsx
├── tsconfig.json
├── types
│ └── custom.d.ts
└── webpack.config.js
Each component is exported as a named module. In WebPack I grab each .ts file as an entry, pass it through ts-loader and output it to the dist folder within another folder with the name of the module. Then I process the TypeScript declaration files and send them to this folder structure.
With an index.js file in root folder I import each module from their folder, and export it as a named module using commonjs syntax.
// ./index.js
exports.Span = require('./dist/Span').Span;
exports.Tag = require('./dist/Tag').Tag;
In package.json I declare the files of my npm module as [ "/dist", "index.js" ]; Thus, the published npm module will be:
.
├── dist
│ ├── Span
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ └── index.js.map
│ └── Tag
│ ├── index.d.ts
│ ├── index.js
│ └── index.js.map
└── index.js
Finally, from my client code I can import those components as named modules, like:
// client code
import { Span, Tag } from 'components_library_example';
My questions are:
Currently the css files are not loaded.
- Is there any reason why my client code can't read the inlined css code?
- Another solution would be to use
MiniCssExtractPluginto extract the css, and import the styles fromindex.js; easy in theory, but actually, it seems not possible. Is there any good approach there?
Currently, when I import the components, typescript is not recognizing the declaration files, so I loose all types.
- ¿How can I export the modules in
index.jsin order to maintain the access to the .d.ts declaration files?
- ¿How can I export the modules in
Thanks!
Note: my webpack conf:
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const nodeExternals = require('webpack-node-externals');
module.exports = {
name: 'server',
entry: {
Span: path.join(__dirname, 'src/Span/index.tsx'),
Tag: path.join(__dirname, 'src/Tag/index.tsx'),
},
output: {
filename: '[name]/index.js',
path: path.join(__dirname, 'dist'),
libraryTarget: 'commonjs2',
globalObject: "(typeof self !== 'undefined' ? self : this)",
library: 'MyLib',
umdNamedDefine: true,
},
target: 'node',
devtool: '#source-map',
externals: [nodeExternals(), 'react'],
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx', '.svg'],
},
module: {
rules: [
{
test: /\.(js|jsx|ts|tsx)$/,
loader: ['ts-loader'],
exclude: /node_modules/,
},
{
test: /\.(less|css)$/,
use: ['css-loader', 'less-loader'],
},
{
test: /\.svg$/,
use: ['@svgr/webpack'],
},
],
},
stats: 'errors-only',
plugins: [
new CleanWebpackPlugin({
dry: false,
verbose: true,
protectWebpackAssets: false,
cleanOnceBeforeBuildPatterns: [path.join(__dirname, 'dist', '/**/*')],
}),
],
};