/* someFile.js */ import { someFunc } from 'path/to/helpers.js'
/* helpers.js */ export function someFunc() { /* ... */ }
<!-- ES6 Modules --> <script type="module" src="/path/to/someFile.js"></script>
<!-- --> <script nomodule src="/path/to/someFileFallback.js"></script>
<script type="module" src="/path/to/someFile.js"></script> <script nomodule src="/path/to/someFileFallback.js"></script>
/* .babelrc.js */ module.exports = { presets: [ ['@babel/preset-env', { useBuiltIns: 'entry', /* ... */ }] ], /* ... */ };
/* */ import 'core-js';
/* */ import "core-js/modules/es6.array.copy-within"; import "core-js/modules/es6.array.fill"; import "core-js/modules/es6.array.find"; /* - */
/* .babelrc.js */ module.exports = { presets: [ ['@babel/preset-env', { useBuiltIns: 'usage', /* ... */ }] ], /* ... */ };
/* */ function sortStrings(strings) { return strings.sort(); } function createResolvedPromise() { return Promise.resolve(); }
/* */ import "core-js/modules/es6.array.sort"; import "core-js/modules/es6.promise"; function sortStrings(strings) { return strings.sort(); } function createResolvedPromise() { return Promise.resolve(); }
/* .babelrc.js */ module.exports = { presets: [ ['@babel/preset-env', { useBuiltIns: 'usage', // , , debug: true, // exclude: ['es6.regexp.to-string', 'es6.number.constructor'], /* ... */ }] ], /* ... */ };
/* .browserslistrc */ > 0.5% IE 10
/* package.json */ { "scripts": { /* ... */ "build": "NODE_ENV=production webpack /.../", "build:fallback": "BROWSERS_ENV=fallback npm run build", "build:modern": "BROWSERS_ENV=modern npm run build" }, /* ... */ }
/* .babelrc.js */ const isModern = process.env.BROWSERS_ENV === 'modern'; module.exports = { presets: [ ['@babel/preset-env', { useBuiltIns: 'usage', // Modern Build ES6 modules, // Fallback Build .browsersrc targets: isModern ? { esmodules: true } : undefined, /* ... */ }] ], /* ... */ ], };
// dist/ // html- index.html // Modern Build' modern/ ... // Fallback Build' fallback/ ...
/* index.html */ <html> <head> <!-- ... --> </head> <body> <!-- ... --> <script type="module" src="/modern/js/app.540601d23b6d03413d5b.js"></script> <script nomodule src="/fallback/js/app.4d03e1af64f68111703e.js"></script> </body> </html>
/* getFilePath.js */ /* , */ const path = require('path'); const isModern = process.env.BROWSERS_ENV === 'modern'; const prefix = isModern ? 'modern' : 'fallback'; module.exports = relativePath => ( path.join(prefix, relativePath) );
/* webpack.prod.config.js */ const getFilePath = require('path/to/getFilePath'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = { mode: 'production', output: { path: 'dist', filename: getFilePath('js/[name].[contenthash].js'), }, plugins: [ new MiniCssExtractPlugin({ filename: getFilePath('css/[name].[contenthash].css'), }), /* ... */ ], /* ... */ }
/* webpack.prod.config.js */ const getFilePath = require('path/to/getFilePath'); const WebpackManifestPlugin = require('webpack-manifest-plugin'); module.exports = { mode: 'production', plugins: [ new WebpackManifestPlugin({ fileName: getFilePath('manifest.json'), }), /* ... */ ], /* ... */ }
/* manifest.json */ { "app.js": "/fallback/js/app.4d03e1af64f68111703e.js", /* ... */ }
/* webpack.prod.config.js */ const HtmlWebpackPlugin = require('html-webpack-plugin'); const ModernBuildPlugin = require('path/to/ModernBuildPlugin'); module.exports = { mode: 'production', plugins: [ ...(isModern ? [ // html- Modern Build new HtmlWebpackPlugin({ filename: 'index.html', }), new ModernBuildPlugin(), ] : []), /* ... */ ], /* ... */ }
/* ModernBuildPlugin.js */ // Safari 10.1 nomodule. // Safari . // : // https://gist.github.com/samthor/64b114e4a4f539915a95b91ffd340acc const safariFix = '!function(){var e=document,t=e.createE/* ... ... */'; class ModernBuildPlugin { apply(compiler) { const pluginName = 'modern-build-plugin'; // Fallback Build const fallbackManifest = require('path/to/dist/fallback/manifest.json'); compiler.hooks.compilation.tap(pluginName, (compilation) => { // html-webpack-plugin, // HTML compilation.hooks.htmlWebpackPluginAlterAssetTags.tapAsync(pluginName, (data, cb) => { // type="module" modern- data.body.forEach((tag) => { if (tag.tagName === 'script' && tag.attributes) { tag.attributes.type = 'module'; } }); // Safari data.body.push({ tagName: 'script', closeTag: true, innerHTML: safariFix, }); // fallback- nomodule const legacyAsset = { tagName: 'script', closeTag: true, attributes: { src: fallbackManifest['app.js'], nomodule: true, defer: true, }, }; data.body.push(legacyAsset); cb(); }); }); } } module.exports = ModernBuildPlugin;
/* package.json */ { "scripts": { /* ... */ "build:full": "npm run build:fallback && npm run build:modern" }, /* ... */ }
Source: https://habr.com/ru/post/430950/
All Articles