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.