]> git.ipfire.org Git - thirdparty/foundation/foundation-sites.git/commitdiff
Use pull request #11618 from ncoden/chore/fix-externals-config for v6.5.0
authorNicolas Coden <nicolas@ncoden.fr>
Fri, 11 Jan 2019 23:22:57 +0000 (00:22 +0100)
committerNicolas Coden <nicolas@ncoden.fr>
Fri, 11 Jan 2019 23:22:57 +0000 (00:22 +0100)
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 <nicolas@ncoden.fr>
.gitignore
gulp/tasks/javascript.js
gulp/utils.js
package-lock.json
package.json
test/bundle/index.html [new file with mode: 0644]
test/bundle/test_bundle.js [new file with mode: 0644]

index 7b9acaebd5f85b1639d4d372995dd1011c817a42..9672436a763571f389d45711a0ecadd66e8b5f55 100644 (file)
@@ -19,8 +19,8 @@ _build
 .customizer
 
 bower_components
-bundle
-build/*
+./bundle
+./build/*
 /docs2/public/*
 _yardoc
 coverage
index 1e46bce67bcaa875a7e7a96e0dc0670719805035..c35860244cda5ef4862cfb581530cc68e450fca8 100644 (file)
@@ -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: [
index 8c4ccea8bc957e634d188b0311beb5def4ffcaf2..72dbd3e9cd7807e68a830d6c943eaf7de85081df 100644 (file)
@@ -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;
 };
 
index 169a965850f5252b865e06e072ec142031ffe9a2..4c64c29612b964aae91f85ed34c80134016f4beb 100644 (file)
         }
       }
     },
+    "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",
index b0ea3fb1f600abc7a4fae6a501f7e68c260b35ec..20dd7df5adeb8fa0201a81f60be611fb7eec6217 100644 (file)
   "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 (file)
index 0000000..1f28681
--- /dev/null
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+
+  <head>
+    <title>Mocha</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <script src="../../node_modules/chai/chai.js"></script>
+    <script src="../../node_modules/requirejs/require.js"></script>
+    <script src="../../node_modules/jquery/dist/jquery.js"></script>
+    <script src="../../node_modules/mocha/mocha.js"></script>
+    <link rel="stylesheet" href="../../node_modules/mocha/mocha.css" />
+    <link rel="stylesheet" href="../../_build/assets/css/foundation-float.css">
+    <link rel="stylesheet" href="../../node_modules/motion-ui/dist/motion-ui.css">
+  </head>
+
+  <body>
+
+    <div id="mocha"></div>
+
+    <script>
+      mocha.setup({
+        ui: 'bdd',
+        timeout: 5000,
+      });
+
+      chai.should();
+
+      requirejs.config({
+        deps: ['test_bundle'],
+        callback: mocha.run
+      });
+    </script>
+
+  </body>
+</html>
diff --git a/test/bundle/test_bundle.js b/test/bundle/test_bundle.js
new file mode 100644 (file)
index 0000000..33d6d29
--- /dev/null
@@ -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;
+    });
+
+  });
+
+});