From 9ab85c0eaefb017e08f78f6171a321d45a8f1e3f Mon Sep 17 00:00:00 2001
From: Jonas Metzener
Date: Thu, 30 Nov 2017 14:15:07 +0100
Subject: [PATCH 1/4] Add possibility to exclude certain parts from the build
---
app/styles/ember-uikit.scss | 6 +-
index.js | 126 +++++++++++++++++++++++++++++---
tests/dummy/app/styles/app.scss | 2 +-
3 files changed, 119 insertions(+), 15 deletions(-)
diff --git a/app/styles/ember-uikit.scss b/app/styles/ember-uikit.scss
index 036cf4c9..75ce67cd 100644
--- a/app/styles/ember-uikit.scss
+++ b/app/styles/ember-uikit.scss
@@ -1,3 +1,3 @@
-@import 'uikit/src/scss/variables-theme';
-@import 'uikit/src/scss/mixins-theme';
-@import 'uikit/src/scss/uikit-theme';
\ No newline at end of file
+@import 'ember-uikit/variables-theme';
+@import 'ember-uikit/mixins-theme';
+@import 'ember-uikit/uikit-theme';
diff --git a/index.js b/index.js
index 304b7d84..cb4f2fb6 100644
--- a/index.js
+++ b/index.js
@@ -3,28 +3,132 @@
const Funnel = require('broccoli-funnel');
const Merge = require('broccoli-merge-trees');
+const path = require('path');
+
+const DEFAULT_OPTIONS = {
+ importUIkitCSS: true,
+ importUIkitJS: true,
+ importUIkitIcons: true,
+ importUIkitAssets: true,
+
+ useIcons: true
+};
+
+// For ember-cli < 2.7 findHost doesnt exist so we backport from that version
+// for earlier version of ember-cli.
+// https://github.com/ember-cli/ember-cli/blame/16e4492c9ebf3348eb0f31df17215810674dbdf6/lib/models/addon.js#L533
module.exports = {
name: 'ember-uikit',
+ findHost() {
+ let fn =
+ this._findHost ||
+ function() {
+ let current = this;
+ let app;
+ do {
+ app = current.app || app;
+ } while (current.parent.parent && (current = current.parent));
+ return app;
+ };
+
+ return fn.call(this);
+ },
+
treeForPublic(tree) {
- let uikitImages = new Funnel('node_modules/uikit/src/images', {
- destDir: '/assets/images/'
- });
+ let uikitAssets =
+ this.uikitOptions.importUIkitAssets &&
+ Funnel(this._getAssetsPath(), {
+ destDir: '/assets/images/components'
+ });
- return new Merge([uikitImages, tree].filter(Boolean));
+ let uikitIcons =
+ this.uikitOptions.useIcons &&
+ this.uikitOptions.importUIkitIcons &&
+ new Funnel(this._getIconsPath(), {
+ destDir: '/assets/images/icons'
+ });
+
+ return new Merge([uikitAssets, uikitIcons, tree].filter(Boolean));
+ },
+
+ treeForStyles(tree) {
+ let uikitStyles =
+ this._hasSass() &&
+ this.uikitOptions.importUIkitCSS &&
+ new Funnel(this._getStylesPath(), {
+ destDir: 'ember-uikit'
+ });
+
+ return new Merge([uikitStyles, tree].filter(Boolean));
},
- included(app) {
+ included() {
this._super.included.apply(this, arguments);
- app.options.sassOptions = app.options.sassOptions || {};
- app.options.sassOptions.includePaths =
- app.options.sassOptions.includePaths || [];
+ this.app = this.findHost();
+
+ let options = Object.assign(
+ Object.assign({}, DEFAULT_OPTIONS),
+ this.app.options['ember-uikit']
+ );
+
+ this.uikitOptions = options;
+
+ if (!this._hasSass() && this.uikitOptions.importUIkitCSS) {
+ // use compiled css version of uikit
+ this.app.import(path.join(this._getStylesPath(), 'uikit.css'));
+ }
+
+ if (this.uikitOptions.importUIkitJS) {
+ this.app.import(path.join(this._getDistPath(), 'js', 'uikit.js'));
+
+ if (this.uikitOptions.useIcons) {
+ this.app.import(path.join(this._getDistPath(), 'js', 'uikit-icons.js'));
+ }
+ }
+ },
+
+ _hasSass() {
+ return !!this.app.project.findAddonByName('ember-cli-sass');
+ },
+
+ _getNodeModulesPath() {
+ return path.relative(process.cwd(), this.app.project.nodeModulesPath);
+ },
+
+ _getDistPath() {
+ return path.join(this._getNodeModulesPath(), 'uikit', 'dist');
+ },
+
+ _getIconsPath() {
+ return path.join(
+ this._getNodeModulesPath(),
+ 'uikit',
+ 'src',
+ 'images',
+ 'icons'
+ );
+ },
+
+ _getAssetsPath() {
+ return path.join(
+ this._getNodeModulesPath(),
+ 'uikit',
+ 'src',
+ 'images',
+ 'components'
+ );
+ },
+
+ _getStylesPath() {
+ let uikitPath = path.join(this._getNodeModulesPath(), 'uikit');
- app.options.sassOptions.includePaths.push('node_modules');
+ if (this._hasSass()) {
+ return path.join(uikitPath, 'src', 'scss');
+ }
- app.import('node_modules/uikit/dist/js/uikit.js');
- app.import('node_modules/uikit/dist/js/uikit-icons.js');
+ return path.join(uikitPath, 'dist', 'css');
}
};
diff --git a/tests/dummy/app/styles/app.scss b/tests/dummy/app/styles/app.scss
index 201da6eb..e0703e73 100644
--- a/tests/dummy/app/styles/app.scss
+++ b/tests/dummy/app/styles/app.scss
@@ -26,4 +26,4 @@ $base-heading-font-weight: 300;
left: 0;
top: 50%;
transform: translateX(calc(-100% - 5px));
-}
\ No newline at end of file
+}
From 89ef48ff119d04c1c6e3ad826a9fa606163eed22 Mon Sep 17 00:00:00 2001
From: Jonas Metzener
Date: Tue, 5 Dec 2017 10:47:43 +0100
Subject: [PATCH 2/4] Add white- and blacklist and add uk-icon to blacklist if
useIcons: false
---
index.js | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 95 insertions(+), 4 deletions(-)
diff --git a/index.js b/index.js
index cb4f2fb6..5637ba6a 100644
--- a/index.js
+++ b/index.js
@@ -11,16 +11,24 @@ const DEFAULT_OPTIONS = {
importUIkitIcons: true,
importUIkitAssets: true,
- useIcons: true
+ useIcons: true,
+
+ whitelist: [],
+ blacklist: []
};
-// For ember-cli < 2.7 findHost doesnt exist so we backport from that version
-// for earlier version of ember-cli.
-// https://github.com/ember-cli/ember-cli/blame/16e4492c9ebf3348eb0f31df17215810674dbdf6/lib/models/addon.js#L533
+const componentDependencies = {
+ 'uk-switcher': ['uk-tab', 'uk-subnav']
+};
module.exports = {
name: 'ember-uikit',
+ /**
+ * For ember-cli < 2.7 findHost doesnt exist so we backport from that version
+ * for earlier version of ember-cli.
+ * https://github.com/ember-cli/ember-cli/blame/16e4492c9ebf3348eb0f31df17215810674dbdf6/lib/models/addon.js#L533
+ */
findHost() {
let fn =
this._findHost ||
@@ -76,6 +84,10 @@ module.exports = {
this.uikitOptions = options;
+ if (!this.uikitOptions.useIcons) {
+ this.uikitOptions.blacklist.push('uk-icon');
+ }
+
if (!this._hasSass() && this.uikitOptions.importUIkitCSS) {
// use compiled css version of uikit
this.app.import(path.join(this._getStylesPath(), 'uikit.css'));
@@ -90,6 +102,85 @@ module.exports = {
}
},
+ _generateWhitelist(whitelist) {
+ let list = [];
+
+ if (!whitelist) {
+ return list;
+ }
+
+ function _addToWhitelist(item) {
+ if (list.indexOf(item) === -1) {
+ list.push(item);
+
+ if (componentDependencies[item]) {
+ componentDependencies[item].forEach(_addToWhitelist);
+ }
+ }
+ }
+
+ whitelist.forEach(_addToWhitelist);
+ return list;
+ },
+
+ treeForAddon(tree) {
+ return this._super.treeForAddon.call(this, this._filterComponents(tree));
+ },
+
+ treeForAddonTemplates(tree) {
+ return this._super.treeForAddonTemplates.call(
+ this,
+ this._filterComponents(tree)
+ );
+ },
+
+ /**
+ * Treeshaking stolen from ember-bootstrap all credits to @kaliber5
+ */
+ _filterComponents(tree) {
+ let whitelist = this._generateWhitelist(this.uikitOptions.whitelist);
+ let blacklist = this.uikitOptions.blacklist || [];
+
+ // exit early if no opts defined
+ if (whitelist.length === 0 && blacklist.length === 0) {
+ return tree;
+ }
+
+ return new Funnel(tree, {
+ exclude: [name => this._excludeComponent(name, whitelist, blacklist)]
+ });
+ },
+
+ _excludeComponent(name, whitelist, blacklist) {
+ let regex = /^(templates\/)?components\//;
+ let isComponent = regex.test(name);
+
+ if (!isComponent) {
+ return false;
+ }
+
+ let baseName = name.replace(regex, '');
+ let firstSeparator = baseName.indexOf('/');
+ if (firstSeparator !== -1) {
+ baseName = baseName.substring(0, firstSeparator);
+ } else {
+ baseName = baseName.substring(0, baseName.lastIndexOf('.'));
+ }
+
+ let isWhitelisted = whitelist.indexOf(baseName) !== -1;
+ let isBlacklisted = blacklist.indexOf(baseName) !== -1;
+
+ if (whitelist.length === 0 && blacklist.length === 0) {
+ return false;
+ }
+
+ if (whitelist.length && blacklist.length === 0) {
+ return !isWhitelisted;
+ }
+
+ return isBlacklisted;
+ },
+
_hasSass() {
return !!this.app.project.findAddonByName('ember-cli-sass');
},
From 4badb1cac12334a485964ab1cc02429d6d060fdf Mon Sep 17 00:00:00 2001
From: Jonas Metzener
Date: Tue, 5 Dec 2017 11:03:45 +0100
Subject: [PATCH 3/4] Add documentation for build options
---
tests/dummy/app/snippets/.eslintrc.js | 3 +
tests/dummy/app/snippets/configuration.js | 12 ++++
tests/dummy/app/templates/index.hbs | 70 +++++++++++++++++++++++
3 files changed, 85 insertions(+)
create mode 100644 tests/dummy/app/snippets/.eslintrc.js
create mode 100644 tests/dummy/app/snippets/configuration.js
diff --git a/tests/dummy/app/snippets/.eslintrc.js b/tests/dummy/app/snippets/.eslintrc.js
new file mode 100644
index 00000000..79ab432f
--- /dev/null
+++ b/tests/dummy/app/snippets/.eslintrc.js
@@ -0,0 +1,3 @@
+module.exports = {
+ rules: { 'no-undef': 'off' }
+};
diff --git a/tests/dummy/app/snippets/configuration.js b/tests/dummy/app/snippets/configuration.js
new file mode 100644
index 00000000..b87662c8
--- /dev/null
+++ b/tests/dummy/app/snippets/configuration.js
@@ -0,0 +1,12 @@
+// ember-cli-build.js
+
+module.exports = function(defaults) {
+ let app = new EmberApp(defaults, {
+ 'ember-uikit': {
+ useIcons: false,
+ whitelist: ['uk-button', 'uk-card']
+ }
+ });
+
+ return app.toTree();
+};
diff --git a/tests/dummy/app/templates/index.hbs b/tests/dummy/app/templates/index.hbs
index 14d3b1d6..cc484894 100644
--- a/tests/dummy/app/templates/index.hbs
+++ b/tests/dummy/app/templates/index.hbs
@@ -22,6 +22,76 @@
include to app/styles/app.scss
.
+Configuration
+
+
+
+
+ Option |
+ Type |
+ Default |
+ Description |
+
+
+
+
+ importUIkitCSS |
+ Boolean |
+ false |
+ Whether to import the CSS of UIkit |
+
+
+ importUIkitJS |
+ Boolean |
+ false |
+ Whether to import the JS of UIkit |
+
+
+ importUIkitAssets |
+ Boolean |
+ false |
+ Whether to import the assets of UIkit |
+
+
+ importUIkitIcons |
+ Boolean |
+ false |
+ Whether to import the icons of UIkit |
+
+
+ useIcons |
+ Boolean |
+ true |
+ Whether to use UIkits icons |
+
+
+ whitelist |
+ String[] |
+ [] |
+
+ A list of included components. Only components in this list will be
+ included in your build. You should never use whitelist
+ and blacklist !
+ |
+
+
+ blacklist |
+ String[] |
+ [] |
+
+ A list of excluded components. Only components not in this list will
+ be included in your build
+ |
+
+
+
+
+
+ Those options can be configured in your ember-cli-build.js
file:
+
+
+{{code-snippet name='configuration.js'}}
+
Contribution
From a539fa1c1d825f6c2aeeff3280d5737d0f6a93f3 Mon Sep 17 00:00:00 2001
From: Jonas Metzener
Date: Tue, 5 Dec 2017 16:06:10 +0100
Subject: [PATCH 4/4] Consistent naming
---
index.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/index.js b/index.js
index 5637ba6a..13f12892 100644
--- a/index.js
+++ b/index.js
@@ -17,7 +17,7 @@ const DEFAULT_OPTIONS = {
blacklist: []
};
-const componentDependencies = {
+const COMPONENT_DEPENDENCIES = {
'uk-switcher': ['uk-tab', 'uk-subnav']
};
@@ -113,8 +113,8 @@ module.exports = {
if (list.indexOf(item) === -1) {
list.push(item);
- if (componentDependencies[item]) {
- componentDependencies[item].forEach(_addToWhitelist);
+ if (COMPONENT_DEPENDENCIES[item]) {
+ COMPONENT_DEPENDENCIES[item].forEach(_addToWhitelist);
}
}
}