J'ai écrit une bibliothèque d'utilitaires et je souhaite les secouer lorsque mon utilisateur publie son application.
Dans Webpack v4, vous devez créer votre module ES6 pour prendre en charge tree-shaking , mais je souhaite également diviser ma build de développement et ma build de production en différentes
Ce que je veux, c'est exactement comme le module NPM de react:
import { someFunc } from 'my-utility-es';
Cela m'amène à me poser des questions.
Si je fais mon tous les modules utilitaires commonjs , je n'obtiendrai jamais d'arborescence , mon application devient tellement énorme.
Si je fais tous mes modules utilitaires Export statique ES6 , je devrai inclure message de développement dans le code de production .
Et publier deux modules (ex: my-utility et my-utility-es ) n'aideront pas, car en développement, mon code ressemble à ceci:
import { someFunc } from 'my-utility';
mais dans le code de production, je devrai le changer en ceci:
// index.js
'use strict';
if (process.env.NODE_ENV === 'production') {
module.exports = require('./cjs/react.production.min.js');
} else {
module.exports = require('./cjs/react.development.js');
}
Comment puis-je résoudre ce problème?
Pour être plus clair, ma build de développement et ma build de production contiennent un code source différent (par exemple: la version de production a supprimé tous les messages d'erreur) .
Donc, spécifier le mode webpack ne me satisfait pas.
3 Réponses :
Tout ce dont vous avez besoin pour résoudre ce problème est d'utiliser le mode a>. Voir Spécifier le mode .
Depuis webpack v4, la spécification du mode configure automatiquement DefinePlugin pour vous:
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'production',
});
Ils mentionnent React par son nom:
Si vous utilisez une bibliothèque comme react, vous devriez en fait constater une baisse significative de la taille du bundle après l'ajout de ce plugin.
Désolé, mais cela ne répond pas à ma question, j'ai mis à jour ma question.
J'ai trouvé la réponse par moi-même, je pense que la meilleure façon de le faire est d'utiliser les macros babel :
import { createMacro } from 'babel-plugin-macros';
function macro({ references, state, babel }) {
state.file.path.node.body.forEach(node => {
if (node.type === 'ImportDeclaration') {
if (node.source.value.includes('myLibrary/macro')) {
if (process.env.NODE_ENV === 'production') {
node.source.value = 'myLibrary/module/production';
} else {
node.source.value = 'myLibrary/module/development';
}
}
}
});
return { keepImports: true };
}
export default createMacro(macro);
Ma mise en œuvre de macro: p>
import { something } from 'myLibrary/macro';
// In webpack development:
// â â â â â â â â
// import { something } from 'myLibrary/development';
// In webpack production:
// â â â â â â â â
// import { something } from 'myLibrary/production';
Voici la meilleure solution que j'ai trouvée, sans obliger l'utilisateur à utiliser les macros Babel ...
crazy-components ComponentA et ComponentB // rollup.config.js
import copy from 'rollup-plugin-copy';
/* ... other imports ... */
export default {
input: 'src/index.js',
/* ... other config ... */
plugins: [
/* ... other plugins ... */
copy({targets: [{src: 'es/package.json', dest: 'dist/esm'}]})
]
};
Soyez tree-shakable, donc si l'utilisateur importe {ComponentA} à partir de 'crazy-components' , le code pour ComponentB ne finit pas dans leur bundle.
Le code de journalisation est supprimé des lots de production.
Les versions CJS sont envoyées vers / dist / cjs , ESM construit en / dist / esm . Les fichiers sont appelés crazy-components.prod.min.js et crazy-components.dev.js.
Seules les versions de développement contiennent le code de journalisation (sans expliquer comment faire tout cela, si vous lisez ceci, vous le savez probablement déjà).
// es/package.json
{
"type": "module"
}
"exports": {
".": {
"import": "./es/index.js",
"require": "./index.js"
},
"./es": "./es/index.js"
},
package.json:// package.json
{
"name": "crazy-components",
"version": "1.0.0",
"main": "index.js",
"module": "es/index.js",
"sideEffects": false
}
Node 12 (avec indicateur) et Node 13+ prend en charge les modules ES nativement .
Ajouter à package.json:
// es/index.js
import {
ComponentA as ComponentA_prod,
ComponentB as ComponentA_prod
} from '../dist/esm/crazy-components.prod.min.js';
import {
ComponentA as ComponentA_dev,
ComponentB as ComponentA_dev
} from '../dist/esm/crazy-components.dev.js';
export const ComponentA = process.env.NODE_ENV === 'production' ? ComponentA_prod : ComponentA_dev;
export const ComponentB = process.env.NODE_ENV === 'production' ? ComponentB_prod : ComponentB_dev;
Vous ne pouvez pas faire trembler l'arborescence en utilisant la syntaxe es5 / commonJS module.exports. Mais comme partagé ci-dessous, vous pouvez utiliser webpack --mode pour supprimer les parties "développement" du code.