From: Nicolas Coden Date: Fri, 11 Jan 2019 23:22:57 +0000 (+0100) Subject: Use pull request #11618 from ncoden/chore/fix-externals-config for v6.5.0 X-Git-Tag: v6.5.2^2~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bef88c402e06bbe03ee4e30da90c2c604018abda;p=thirdparty%2Ffoundation%2Ffoundation-sites.git Use pull request #11618 from ncoden/chore/fix-externals-config for v6.5.0 4d9270f0f chore: fix plugins UMD external names 7f5aa78c2 docs: add documentation for the webpack UMD configuration 4124057ca chore: fix plugins' UMD root variables names 3fa67416e test: add test for imports via AMD 91353dba1 docs: improve description for the webpack externals config in build script a69a577ea docs: improve docs for the root namespace in build script 5e422093c docs: improve docs of the "getUmdEntry" build utility Signed-off-by: Nicolas Coden --- diff --git a/.gitignore b/.gitignore index 7b9acaebd..9672436a7 100644 --- a/.gitignore +++ b/.gitignore @@ -19,8 +19,8 @@ _build .customizer bower_components -bundle -build/* +./bundle +./build/* /docs2/public/* _yardoc coverage diff --git a/gulp/tasks/javascript.js b/gulp/tasks/javascript.js index 1e46bce67..c35860244 100644 --- a/gulp/tasks/javascript.js +++ b/gulp/tasks/javascript.js @@ -16,33 +16,50 @@ var CONFIG = require('../config.js'); // (just throw in foundation.js or foundation.min.js) or you should be using a build // system. -// Generate plugin Externals config for UMD modules +// +// Generate the webpack "Externals" configuration for UMD modules. +// This tells webpack that the modules imported with the listed paths should not +// be included in the build but will be provided later from an external source. +// +// `umdExternals` is used to generate the webpack "externals" configuration: +// an object indicating to different module tools under which name our modules +// are declared. "root" is the global variable name to use in module-less +// environments (or in the namespace if given). +// +// See https://webpack.js.org/configuration/externals/#externals +// var webpackExternalPlugins = Object.assign( + // | Module import path | External source names and paths utils.umdExternals({ - 'jquery': 'jQuery', + 'jquery': { root: 'jQuery' }, }), utils.umdExternals({ - // Import path | Exported file - './foundation.core': 'foundation.core', - './foundation.core.utils': 'foundation.core', - './foundation.core.plugin': 'foundation.core', - './foundation.util.imageLoader': 'foundation.util.imageLoader', - './foundation.util.keyboard': 'foundation.util.keyboard', - './foundation.util.mediaQuery': 'foundation.util.mediaQuery', - './foundation.util.motion': 'foundation.util.motion', - './foundation.util.nest': 'foundation.util.nest', - './foundation.util.timer': 'foundation.util.timer', - './foundation.util.touch': 'foundation.util.touch', - './foundation.util.box': 'foundation.util.box', - './foundation.dropdownMenu': 'foundation.dropdownMenu', - './foundation.drilldown': 'foundation.drilldown', - './foundation.accordionMenu': 'foundation.accordionMenu', - './foundation.accordion': 'foundation.accordion', - './foundation.tabs': 'foundation.tabs', - './foundation.smoothScroll': 'foundation.smoothScroll', - }, { namespace: CONFIG.JS_BUNDLE_NAMESPACE }) + './foundation.core': { root: 'foundation.core', default: './foundation.core' }, + './foundation.core.utils': { root: 'foundation.core', default: './foundation.core' }, + './foundation.core.plugin': { root: 'foundation.core', default: './foundation.core' }, + './foundation.util.imageLoader': { root: 'foundation.util.imageLoader' }, + './foundation.util.keyboard': { root: 'foundation.util.keyboard' }, + './foundation.util.mediaQuery': { root: 'foundation.util.mediaQuery' }, + './foundation.util.motion': { root: 'foundation.util.motion' }, + './foundation.util.nest': { root: 'foundation.util.nest' }, + './foundation.util.timer': { root: 'foundation.util.timer' }, + './foundation.util.touch': { root: 'foundation.util.touch' }, + './foundation.util.box': { root: 'foundation.util.box' }, + './foundation.dropdownMenu': { root: 'foundation.dropdownMenu' }, + './foundation.drilldown': { root: 'foundation.drilldown' }, + './foundation.accordionMenu': { root: 'foundation.accordionMenu' }, + './foundation.accordion': { root: 'foundation.accordion' }, + './foundation.tabs': { root: 'foundation.tabs' }, + './foundation.smoothScroll': { root: 'foundation.smoothScroll' }, + }, { + // Search for the module in this global variable in module-less environments. + namespace: CONFIG.JS_BUNDLE_NAMESPACE + }) ); +// The webpack "output" configuration for UMD modules. +// Makes the modules being exported as UMD modules. In module-less environments, +// modules will be stored in the global variable defined by JS_BUNDLE_NAMESPACE. var webpackOutputAsExternal = { library: [CONFIG.JS_BUNDLE_NAMESPACE, '[name]'], libraryTarget: 'umd', @@ -51,7 +68,8 @@ var webpackOutputAsExternal = { var webpackConfig = { mode: 'development', externals: utils.umdExternals({ - 'jquery': 'jQuery' + // Use the global jQuery object "jQuery" in module-less environments. + 'jquery': { root: 'jQuery' }, }), module: { rules: [ diff --git a/gulp/utils.js b/gulp/utils.js index 8c4ccea8b..72dbd3e9c 100644 --- a/gulp/utils.js +++ b/gulp/utils.js @@ -2,19 +2,60 @@ function arrayClear(array) { return array.filter(function (v) { return !!v }); } -// Convert an external config object for UMD modules -// See: https://webpack.js.org/configuration/externals/#object +/** + * Return the import path/name of an UMD module for the given module format. + * + * @param {string} name - name of the module, used if no other no import path/name can be found. + * @param {object|string} config - external configuration. + * - If a string, returns it (we consider this is the path or name). + * - If an object, returns the property within it according to the given `format`, + * or the "default" property. + * @param {string} format - format of the module to look for, if the configuration is an object. + * + * @return The found import path/name for the module. + */ +function getUmdEntry(name, config, format) { + if (typeof config === 'string') { + return config; + } + if (typeof config === 'object') { + if (config[format] != null) return config[format]; + if (config.default != null) return config.default; + } + return name; +} + +/** + * Generate an configuration object for Webpack Externals for UMD modules. + * See: https://webpack.js.org/configuration/externals/#object + * + * @param {object} externals - Configuration object for external UMD modules. + * For each entry, a string or an object can be provided. + * - If a string, it is used for all module formats. + * - If an object, it is used as is and the "default" property or the module + * name is used for missing formats. + * @param {object} {} options- Additional options: + * - namespace {string} '' - Global variable in which the modules must be + * searched in instead of the root for module-less environments. + * + * @return {object} Generated configuration for Webpack Externals + */ module.exports.umdExternals = function(externals, options) { options = Object.assign({ namespace: '' }, options); - return Object.keys(externals).reduce(function(obj, k) { - obj[k] = { - root: arrayClear([options.namespace, externals[k]]), - amd: k, - commonjs: k, - commonjs2: k, + var config = {}; + + Object.keys(externals).forEach(function (name) { + var entryConfig = externals[name]; + + config[name] = { + root: arrayClear([ options.namespace, getUmdEntry(name, entryConfig, 'root') ]), + amd: getUmdEntry(name, entryConfig, 'amd'), + commonjs: getUmdEntry(name, entryConfig, 'commonjs'), + commonjs2: getUmdEntry(name, entryConfig, 'commonjs2'), }; - return obj; }, {}); + + return config; }; diff --git a/package-lock.json b/package-lock.json index 169a96585..4c64c2961 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13527,6 +13527,12 @@ } } }, + "requirejs": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz", + "integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==", + "dev": true + }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", diff --git a/package.json b/package.json index b0ea3fb1f..20dd7df5a 100644 --- a/package.json +++ b/package.json @@ -12,13 +12,14 @@ "homepage": "http://foundation.zurb.com/sites", "scripts": { "start": "gulp", - "test": "npm run test:sass && npm run test:javascript:units", + "test": "npm run test:sass && npm run test:javascript:units && npm run test:bundle", "test:ci": "npm run test:sass && npm run test:javascript:ci", "test:sass": "mocha test/sass/test_sass.js --colors", "test:javascript:transpile": "gulp sass:foundation --color && gulp test:transpile-js --color", "test:javascript:units": "npm run test:javascript:transpile && mocha-headless-chrome -a ignore-resource-errors -a no-sandbox -f test/javascript/index.html", "test:javascript:browserstack": "npm run test:javascript:transpile && browserstack-runner", "test:javascript:ci": "npm run test:javascript:transpile && mocha-headless-chrome -a ignore-resource-errors -a no-sandbox -f test/javascript/index.html && browserstack-runner", + "test:bundle": "mocha-headless-chrome -a ignore-resource-errors -a no-sandbox -f test/bundle/index.html", "test:visual": "gulp test --color", "lockdeps": "npm i && rimraf yarn.lock && yarn import && rimraf shrinkwrap.yaml && pnpm import", "relockdeps": "rimraf package-lock.json && npm run lockdeps", @@ -86,6 +87,7 @@ "parker": "^1.0.0-alpha.0", "prettyjson": "^1.1.3", "require-dir": "^1.0.0", + "requirejs": "^2.3.6", "rimraf": "^2.6.1", "rollup": "^0.65.2", "rollup-plugin-babel": "^4.0.3", diff --git a/test/bundle/index.html b/test/bundle/index.html new file mode 100644 index 000000000..1f286819b --- /dev/null +++ b/test/bundle/index.html @@ -0,0 +1,36 @@ + + + + + Mocha + + + + + + + + + + + + + +
+ + + + + diff --git a/test/bundle/test_bundle.js b/test/bundle/test_bundle.js new file mode 100644 index 000000000..33d6d298a --- /dev/null +++ b/test/bundle/test_bundle.js @@ -0,0 +1,14 @@ +describe('Foundation bundle', function() { + + it('can be imported via AMD', function (done) { + + require(['../../_build/assets/js/foundation'], function(foundation) { + foundation.Foundation.should.be.an('object'); + done(); + }, function (err) { + if (err) throw err; + }); + + }); + +});