He creado un paquete NPM relativamente pequeño que consta de aproximadamente 5 clases ES6 diferentes contenidas en un archivo cada una, todas se parecen a esto:
export default class MyClass {
// ...
}
Luego configuré un punto de entrada para mi paquete que se ve así:
export { default as MyClass } from './my-class.js';
export { default as MyOtherClass } from './my-other-class.js';
Luego ejecuté el punto de entrada a través de webpack y babel terminando con un index.js transpilado y minificado
Instalar e importar el paquete funciona bien, pero cuando hago lo siguiente desde mi código de cliente:
import { MyClass } from 'my-package';
No solo importa "MyClass", importa todo el archivo, incluidas todas las dependencias de cada clase (algunas de mis clases tienen enormes dependencias).
Supuse que así es como funciona webpack cuando intentas importar partes de un paquete ya incluido. Así que configuré mi configuración de paquete web local para ejecutar también a node_modules/my-package
través de babel y luego intenté:
import { MyClass } from 'my-package/src/index.js';
Pero incluso esto importa todas las clases exportadas por index.js. Lo único que parece funcionar de la manera que quiero es si lo hago:
import MyClass from 'my-package/src/my-class.js';
Pero prefiero mucho:
- Poder importar el archivo transpilado y minificado para que no tenga que decirle a webpack que ejecute babel dentro de node_modules y
- Poder importar cada clase individual directamente desde mi punto de entrada en lugar de tener que ingresar la ruta a cada archivo
¿Cuál es la mejor práctica aquí? ¿Cómo logran otros configuraciones similares? Me di cuenta de que GlideJS tiene una versión ESM de su paquete que le permite importar solo las cosas que necesita sin tener que ejecutar babel a través de él, por ejemplo.
El paquete en cuestión: https://github.com/powerbuoy/sleek-ui
webpack.config.js
const path = require('path');
module.exports = {
entry: {
'sleek-ui': './src/js/sleek-ui.js'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
library: 'sleek-ui', // NOTE: Before adding this and libraryTarget I got errors saying "MyClass() is not a constructor" for some reason...
libraryTarget: 'umd'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
]
}
]
}
};
package.json
"name": "sleek-ui",
"version": "1.0.0",
"description": "Lightweight SASS and JS library for common UI elements",
"main": "dist/sleek-ui.js",
"sideEffects": false, // NOTE: Added this from Abhishek's article but it changed nothing for me :/
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --mode production"
},
"repository": {
"type": "git",
"url": "git+https://github.com/powerbuoy/sleek-ui.git"
},
"author": "Andreas Lagerkvist",
"license": "GPL-2.0-or-later",
"bugs": {
"url": "https://github.com/powerbuoy/sleek-ui/issues"
},
"homepage": "https://github.com/powerbuoy/sleek-ui#readme",
"devDependencies": {
"@babel/core": "^7.8.6",
"@babel/preset-env": "^7.8.6",
"babel-loader": "^8.0.6",
"webpack": "^4.42.0",
"webpack-cli": "^3.3.11"
},
"dependencies": {
"@glidejs/glide": "^3.4.1",
"normalize.css": "^8.0.1"
}
}
import { MyClass } from 'my-package/src/MyClass';
. También puede eliminar el paquete de compilación src para acortar la ruta del archivo.
main
atributo (punto de entrada) en el paquete package.json de su lib? Revisa tu construcción. ¿Y cómo está empaquetando su paquete lib?