-
Notifications
You must be signed in to change notification settings - Fork 33
/
index.js
176 lines (139 loc) · 5.38 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
'use strict';
const fs = require('fs');
const path = require('path');
const Funnel = require('broccoli-funnel');
const Merge = require('broccoli-merge-trees');
const buildTailwind = require('./lib/build-tailwind');
const mv = require('broccoli-stew').mv;
const debugTree = require('broccoli-debug').buildDebugCallback(`ember-cli-tailwind:${this.name}`);
const buildDestinations = {
dummy: {
path: 'tests/dummy/app',
type: 'app'
},
app: {
path: 'app',
type: 'app'
},
addon: {
path: 'addon',
type: 'addon'
}
};
const validBuildTargets = Object.keys(buildDestinations);
module.exports = {
name: 'ember-cli-tailwind',
isDevelopingAddon() {
return true;
},
included(includer) {
this._super.included.apply(this, arguments);
// If this is set, show a warning
let explicitBuildTarget = includer.options &&
includer.options[this.name] &&
includer.options[this.name]['buildTarget'];
if (explicitBuildTarget) {
this.ui.writeWarnLine('You no longer need to specify a buildTarget - it is now derived from your project files. Please delete this config option.')
}
let buildTarget;
if (fs.existsSync(!this.project.isEmberCLIAddon() && this.project.root + '/app/tailwind')) {
buildTarget = 'app';
} else if (fs.existsSync(includer.root + '/addon/tailwind')) {
buildTarget = 'addon';
} else if (includer.name === "dummy" && fs.existsSync(process.cwd() + '/tests/dummy/app/tailwind')) {
buildTarget = 'dummy';
}
if (!this._validateBuildTarget(buildTarget, includer)) {
return;
}
let buildConfig = buildDestinations[buildTarget];
if (this._shouldIncludeStyleguide()) {
this.import('vendor/etw.css');
}
this.projectType = buildConfig.type;
this.tailwindInputPath = this._getInputPath(this.parent.root, buildConfig.path);
},
treeForStyles(tree) {
let trees = tree ? [ tree ] : [];
if (this.projectType === 'app' && this._hasTailwindConfig() && this._shouldBuildTailwind()) {
trees.push(mv(buildTailwind(this), 'app/styles'));
}
return debugTree(new Merge(trees), 'tree-for-styles');
},
treeForAddonStyles(tree) {
let trees = tree ? [ tree ] : [];
if (this.projectType === 'addon' && this._hasTailwindConfig() && this._shouldBuildTailwind()) {
trees.push(mv(buildTailwind(this), 'addon/styles'));
}
return debugTree(new Merge(trees), 'tree-for-addon-styles');
},
treeForApp(tree) {
let appTree = this._super(tree);
if (!this._shouldIncludeStyleguide()) {
appTree = new Funnel(appTree, {
exclude: ['**/instance-initializers/ember-cli-tailwind.js'],
});
}
return debugTree(appTree, 'tree-for-app');
},
_shouldIncludeStyleguide() {
let envConfig = this.parent.config(process.env.EMBER_ENV)[this.name];
let shouldOverrideDefault = envConfig !== undefined && envConfig.shouldIncludeStyleguide !== undefined;
return shouldOverrideDefault ? envConfig.shouldIncludeStyleguide : process.env.EMBER_ENV !== 'production';
},
// Private
_getInputPath(root, inputPath) {
if (typeof inputPath !== 'string') {
this.ui.writeWarnLine('Unable to process Tailwind styles for a non-string tree');
return;
}
let fullPath = path.join(root, inputPath, 'tailwind');
if (fs.existsSync(path.join(fullPath, 'config', 'tailwind.js'))) {
return fullPath;
}
},
_hasTailwindConfig() {
return this.tailwindInputPath;
},
_shouldBuildTailwind() {
let shouldBuildTailwind = this._config().shouldBuildTailwind;
return (shouldBuildTailwind !== undefined) ? shouldBuildTailwind : true;
},
_validateBuildTarget(buildTarget) {
// If no build target is found, but we're not in addon, assume something is definitely wrong
// and print the warning line so app consumers won't be in the dark about their styles not
// showing up. On the other hand, if it IS an addon, don't print the warning message since
// since this hook will be run twice regardless of whether or not they're intending to use
// tailwind in both their addon and dummy app.
if (!buildTarget) {
if (!this._isAddon()) {
this.ui.writeWarnLine('No build target was detected for ember-cli-tailwind. Tailwind is not being included in your project.')
}
return false;
}
if (buildTarget && !validBuildTargets.includes(buildTarget)) {
this.ui.writeWarnLine('Your buildTarget is invalid. Valid targets are "app", "addon", or "dummy".')
return false;
}
if (this._tailwindAddonConfigExists() && !this._isDependency()) {
this.ui.writeError('A Tailwind config was detected in the addon folder, but `ember-cli-tailwind` is not listed as a dependency. Please make sure `ember-cli-tailwind` is listed in `dependencies` (NOT `devDependencies`).');
return false;
}
return true;
},
_isAddon() {
const keywords = this.parent.pkg.keywords;
return (keywords && keywords.indexOf('ember-addon') !== -1);
},
_tailwindAddonConfigExists() {
return fs.existsSync(path.join(this.parent.root, 'addon', 'tailwind'));
},
// Check that `ember-cli-tailwind` is listed in `dependencies` (as opposed to `devDependencies`)
_isDependency() {
let deps = this.parent.pkg.dependencies;
return deps && Object.keys(deps).includes(this.name);
},
_config() {
return this.parent.config(process.env.EMBER_ENV)[this.name] || {};
}
};