Skip to content

Commit 5d376a5

Browse files
committed
PatternLab loads the pattern engines from the config first, before fallback to scanning node_modules
1 parent 1d28ab0 commit 5d376a5

File tree

12 files changed

+199
-24
lines changed

12 files changed

+199
-24
lines changed

Diff for: packages/cli/test/fixtures/patternlab-config.json

+16-1
Original file line numberDiff line numberDiff line change
@@ -83,5 +83,20 @@
8383
"color": "dark",
8484
"density": "compact",
8585
"layout": "horizontal"
86-
}
86+
},
87+
"engines": {
88+
"mustache": {
89+
"package":"@pattern-lab/engine-mustache",
90+
"fileExtensions": [
91+
"mustache"
92+
]
93+
},
94+
"handlebars": {
95+
"package": "@pattern-lab/engine-handlebars",
96+
"fileExtensions": [
97+
"handlebars",
98+
"hbs"
99+
]
100+
}
101+
},
87102
}

Diff for: packages/core/patternlab-config.json

+8
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@
8888
"density": "compact",
8989
"layout": "horizontal"
9090
},
91+
"engines": {
92+
"mustache": {
93+
"package":"@pattern-lab/engine-mustache",
94+
"fileExtensions": [
95+
"mustache"
96+
]
97+
}
98+
},
9199
"uikits": [
92100
{
93101
"name": "uikit-workshop",

Diff for: packages/core/src/lib/pattern_engines.js

+81-22
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,19 @@ function findEngineModulesInDirectory(dir) {
5656
return foundEngines;
5757
}
5858

59+
function findEnginesInConfig(config) {
60+
if ('engines' in config) {
61+
return config.engines;
62+
}
63+
logger.warning(
64+
"Scanning the 'node_modules' folder for pattern engines is deprecated and will be removed in v6."
65+
);
66+
logger.warning(
67+
'To configure your engines in patternlab-config.json, see https://patternlab.io/docs/editing-the-configuration-options/#heading-engines'
68+
);
69+
return null;
70+
}
71+
5972
//
6073
// PatternEngines: the main export of this module
6174
//
@@ -80,18 +93,14 @@ const PatternEngines = Object.create({
8093
loadAllEngines: function(patternLabConfig) {
8194
const self = this;
8295

83-
// Try to load engines! We scan for engines at each path specified above. This
84-
// function is kind of a big deal.
85-
enginesDirectories.forEach(function(engineDirectory) {
86-
const enginesInThisDir = findEngineModulesInDirectory(
87-
engineDirectory.path
88-
);
89-
90-
logger.debug(`Loading engines from ${engineDirectory.displayName}...`);
96+
// Try to load engines! We load the engines configured in patternlab-config.json
97+
const enginesInConfig = findEnginesInConfig(patternLabConfig);
9198

92-
// find all engine-named things in this directory and try to load them,
93-
// unless it's already been loaded.
94-
enginesInThisDir.forEach(function(engineDiscovery) {
99+
if (enginesInConfig) {
100+
// Try loading each of the configured pattern engines
101+
// eslint-disable-next-line guard-for-in
102+
for (const name in enginesInConfig) {
103+
const engineConfig = enginesInConfig[name];
95104
let errorMessage;
96105
const successMessage = 'good to go';
97106

@@ -100,30 +109,80 @@ const PatternEngines = Object.create({
100109
// of course. Also pass the pattern lab config object into
101110
// the engine's closure scope so it can know things about
102111
// things.
103-
if (self[engineDiscovery.name]) {
112+
if (self[name]) {
104113
throw new Error('already loaded, skipping.');
105114
}
106-
self[engineDiscovery.name] = require(engineDiscovery.modulePath);
107-
if (
108-
typeof self[engineDiscovery.name].usePatternLabConfig === 'function'
109-
) {
110-
self[engineDiscovery.name].usePatternLabConfig(patternLabConfig);
111-
}
112-
if (typeof self[engineDiscovery.name].spawnMeta === 'function') {
113-
self[engineDiscovery.name].spawnMeta(patternLabConfig);
115+
if ('package' in engineConfig) {
116+
self[name] = require(engineConfig.package);
117+
if (typeof self[name].usePatternLabConfig === 'function') {
118+
self[name].usePatternLabConfig(patternLabConfig);
119+
}
120+
if (typeof self[name].spawnMeta === 'function') {
121+
self[name].spawnMeta(patternLabConfig);
122+
}
123+
} else {
124+
logger.warning(
125+
`Engine ${name} not configured correctly. Please configure your engines in patternlab-config.json as documented in https://patternlab.io/docs/editing-the-configuration-options/#heading-engines`
126+
);
114127
}
115128
} catch (err) {
116129
errorMessage = err.message;
117130
} finally {
118131
// report on the status of the engine, one way or another!
119132
logger.info(
120-
`Pattern Engine ${engineDiscovery.name}: ${
133+
`Pattern Engine ${engineConfig.extension}: ${
121134
errorMessage ? errorMessage : successMessage
122135
}`
123136
);
124137
}
138+
}
139+
} else {
140+
// Try to load engines! We scan for engines at each path specified above. This
141+
// function is kind of a big deal.
142+
enginesDirectories.forEach(function(engineDirectory) {
143+
const enginesInThisDir = findEngineModulesInDirectory(
144+
engineDirectory.path
145+
);
146+
147+
logger.debug(`Loading engines from ${engineDirectory.displayName}...`);
148+
149+
// find all engine-named things in this directory and try to load them,
150+
// unless it's already been loaded.
151+
enginesInThisDir.forEach(function(engineDiscovery) {
152+
let errorMessage;
153+
const successMessage = 'good to go';
154+
155+
try {
156+
// Give it a try! load 'er up. But not if we already have,
157+
// of course. Also pass the pattern lab config object into
158+
// the engine's closure scope so it can know things about
159+
// things.
160+
if (self[engineDiscovery.name]) {
161+
throw new Error('already loaded, skipping.');
162+
}
163+
self[engineDiscovery.name] = require(engineDiscovery.modulePath);
164+
if (
165+
typeof self[engineDiscovery.name].usePatternLabConfig ===
166+
'function'
167+
) {
168+
self[engineDiscovery.name].usePatternLabConfig(patternLabConfig);
169+
}
170+
if (typeof self[engineDiscovery.name].spawnMeta === 'function') {
171+
self[engineDiscovery.name].spawnMeta(patternLabConfig);
172+
}
173+
} catch (err) {
174+
errorMessage = err.message;
175+
} finally {
176+
// report on the status of the engine, one way or another!
177+
logger.info(
178+
`Pattern Engine ${engineDiscovery.name}: ${
179+
errorMessage ? errorMessage : successMessage
180+
}`
181+
);
182+
}
183+
});
125184
});
126-
});
185+
}
127186

128187
// Complain if for some reason we haven't loaded any engines.
129188
if (Object.keys(self).length === 0) {

Diff for: packages/core/test/util/patternlab-config.json

+15
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,21 @@
7373
"density": "compact",
7474
"layout": "horizontal"
7575
},
76+
"engines": {
77+
"mustache": {
78+
"package":"@pattern-lab/engine-mustache",
79+
"fileExtensions": [
80+
"mustache"
81+
]
82+
},
83+
"handlebars": {
84+
"package": "@pattern-lab/engine-handlebars",
85+
"fileExtensions": [
86+
"handlebars",
87+
"hbs"
88+
]
89+
}
90+
},
7691
"uikits": [
7792
{
7893
"name": "uikit-workshop",

Diff for: packages/development-edition-engine-handlebars/patternlab-config.json

+5
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@
9595
],
9696
"engines": {
9797
"handlebars": {
98+
"package": "@pattern-lab/engine-handlebars",
99+
"fileExtensions": [
100+
"handlebars",
101+
"hbs"
102+
],
98103
"extend": "helpers/*.js"
99104
}
100105
},

Diff for: packages/development-edition-engine-react/patternlab-config.json

+14
Original file line numberDiff line numberDiff line change
@@ -87,5 +87,19 @@
8787
"color": "dark",
8888
"density": "compact",
8989
"layout": "horizontal"
90+
},
91+
"engines": {
92+
"mustache": {
93+
"package":"@pattern-lab/engine-mustache",
94+
"fileExtensions": [
95+
"mustache"
96+
]
97+
},
98+
"handlebars": {
99+
"package": "@pattern-lab/engine-react",
100+
"fileExtensions": [
101+
"jsx"
102+
]
103+
}
90104
}
91105
}

Diff for: packages/development-edition-engine-twig/patternlab-config.json

+10
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,17 @@
103103
}
104104
],
105105
"engines": {
106+
"mustache": {
107+
"package":"@pattern-lab/engine-mustache",
108+
"fileExtensions": [
109+
"mustache"
110+
]
111+
},
106112
"twig": {
113+
"package": "@pattern-lab/engine-twig",
114+
"fileExtensions": [
115+
"twig"
116+
],
107117
"namespaces": {
108118
"atoms": "source/_patterns/00-atoms/",
109119
"molecules": "source/_patterns/01-molecules/",

Diff for: packages/docs/src/docs/advanced-config-options.md

+30-1
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,35 @@ Sets the panel name and language for the code tab on the styleguide. Since this
164164

165165
**default**: `mustache`
166166

167+
### engines
168+
169+
An engine is a wrapper around a templating library like Mustache, Handlebars, Twig or others. An engine package
170+
is the bridge between PatternLab and the standalone NPM package supporting the templating language.
171+
172+
`engines` accepts an map of Engine objects. The mandatory properties for each PatternLab engine are:
173+
174+
- `package`: the NodeJS package name. Add the package of the engine as a dependency in `package.json` before you configure it here.
175+
- `fileExtensions`: list of pattern file extensions which will be handled by this pattern engine.
176+
177+
Other engine specific configuration options can be added and will be passed to the pattern engine at loading time. See the NPM package documentation for the properties each pattern engine supports.
178+
179+
**default**:
180+
181+
```javascript
182+
"engines": {
183+
"mustache": {
184+
"package": "@pattern-lab/engine-mustache",
185+
"extensions": [
186+
"mustache"
187+
],
188+
...
189+
}
190+
}
191+
```
192+
193+
Configuring the engines in the config file was introduced in v5.14. The fallback lookup mode by scanning the
194+
`node_modules` folder is **deprecated** will be removed in v6.
195+
167196
### patternStateCascade
168197

169198
See the [Pattern State Documentation](/docs/using-pattern-states/)
@@ -336,7 +365,7 @@ Important details:
336365
- the [default `paths.source` object paths](https://github.com/pattern-lab/patternlab-node/pull/840/commits/a4961bd5d696a05fb516cdd951163b0f918d5e19) within `patternlab-config.json` are now relative to the current UIKit. See the [structure of uikit-workshop](https://github.com/pattern-lab/patternlab-node/tree/master/packages/uikit-workshop) for more info
337366
- the [default `paths.public` object paths](https://github.com/pattern-lab/patternlab-node/pull/840/commits/812bab3659f504043e8b61b1dc1cdac71f248449) within `patternlab-config.json` are now relative to the current UIKit's `outputDir`. Absolute paths will no longer work. Someone could test putting an absolute path in a UIKit `outputDir` property and see what happens I suppose.
338367
- `dependencyGraph.json` has moved to the project root rather than `public/` as we should only retain one
339-
- The lookup of the uikit by `name` is deprecated and the user will be notified of it. If the `package` property isn't defined, there is a default fallback lookup strategy where the value of `name` is tried as:
368+
- The lookup of the uikit by `name` is **deprecated** and will be removed in v6. The user will be notified of it. If the `package` property isn't defined, there is a default fallback lookup strategy where the value of `name` is tried as:
340369
- `<name>`
341370
- `uikit-<name>`
342371
- `@pattern-lab/<name>`

Diff for: packages/edition-node-gulp/patternlab-config.json

+8
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,14 @@
8787
"density": "compact",
8888
"layout": "horizontal"
8989
},
90+
"engines": {
91+
"mustache": {
92+
"package": "@pattern-lab/engine-mustache",
93+
"fileExtensions": [
94+
"mustache"
95+
]
96+
}
97+
},
9098
"uikits": [
9199
{
92100
"name": "uikit-workshop",

Diff for: packages/edition-node/patternlab-config.json

+4
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@
9999
],
100100
"engines": {
101101
"handlebars": {
102+
"package": "@pattern-lab/engine-handlebars",
103+
"fileExtensions": [
104+
"hbs"
105+
],
102106
"extend": "helpers/*.js"
103107
}
104108
}

Diff for: packages/edition-twig/patternlab-config.json

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
{
22
"engines": {
33
"twig": {
4+
"package": "@pattern-lab/engine-twig-php",
5+
"fileExtensions": [
6+
"twig"
7+
],
48
"namespaces": [
59
{
610
"id": "uikit",

Diff for: packages/starterkit-twig-demo/patternlab-config.json

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
{
22
"engines": {
33
"twig": {
4+
"package": "@pattern-lab/engine-twig-php",
5+
"fileExtensions": [
6+
"twig"
7+
],
48
"namespaces": [
59
{
610
"id": "atoms",

0 commit comments

Comments
 (0)