Skip to content

Commit

Permalink
PatternLab loads the pattern engines from the config first, before fa…
Browse files Browse the repository at this point in the history
…llback to scanning node_modules
  • Loading branch information
ringods committed Sep 2, 2020
1 parent 1d28ab0 commit 5d376a5
Show file tree
Hide file tree
Showing 12 changed files with 199 additions and 24 deletions.
17 changes: 16 additions & 1 deletion packages/cli/test/fixtures/patternlab-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,20 @@
"color": "dark",
"density": "compact",
"layout": "horizontal"
}
},
"engines": {
"mustache": {
"package":"@pattern-lab/engine-mustache",
"fileExtensions": [
"mustache"
]
},
"handlebars": {
"package": "@pattern-lab/engine-handlebars",
"fileExtensions": [
"handlebars",
"hbs"
]
}
},
}
8 changes: 8 additions & 0 deletions packages/core/patternlab-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@
"density": "compact",
"layout": "horizontal"
},
"engines": {
"mustache": {
"package":"@pattern-lab/engine-mustache",
"fileExtensions": [
"mustache"
]
}
},
"uikits": [
{
"name": "uikit-workshop",
Expand Down
103 changes: 81 additions & 22 deletions packages/core/src/lib/pattern_engines.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,19 @@ function findEngineModulesInDirectory(dir) {
return foundEngines;
}

function findEnginesInConfig(config) {
if ('engines' in config) {
return config.engines;
}
logger.warning(
"Scanning the 'node_modules' folder for pattern engines is deprecated and will be removed in v6."
);
logger.warning(
'To configure your engines in patternlab-config.json, see https://patternlab.io/docs/editing-the-configuration-options/#heading-engines'
);
return null;
}

//
// PatternEngines: the main export of this module
//
Expand All @@ -80,18 +93,14 @@ const PatternEngines = Object.create({
loadAllEngines: function(patternLabConfig) {
const self = this;

// Try to load engines! We scan for engines at each path specified above. This
// function is kind of a big deal.
enginesDirectories.forEach(function(engineDirectory) {
const enginesInThisDir = findEngineModulesInDirectory(
engineDirectory.path
);

logger.debug(`Loading engines from ${engineDirectory.displayName}...`);
// Try to load engines! We load the engines configured in patternlab-config.json
const enginesInConfig = findEnginesInConfig(patternLabConfig);

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

Expand All @@ -100,30 +109,80 @@ const PatternEngines = Object.create({
// of course. Also pass the pattern lab config object into
// the engine's closure scope so it can know things about
// things.
if (self[engineDiscovery.name]) {
if (self[name]) {
throw new Error('already loaded, skipping.');
}
self[engineDiscovery.name] = require(engineDiscovery.modulePath);
if (
typeof self[engineDiscovery.name].usePatternLabConfig === 'function'
) {
self[engineDiscovery.name].usePatternLabConfig(patternLabConfig);
}
if (typeof self[engineDiscovery.name].spawnMeta === 'function') {
self[engineDiscovery.name].spawnMeta(patternLabConfig);
if ('package' in engineConfig) {
self[name] = require(engineConfig.package);
if (typeof self[name].usePatternLabConfig === 'function') {
self[name].usePatternLabConfig(patternLabConfig);
}
if (typeof self[name].spawnMeta === 'function') {
self[name].spawnMeta(patternLabConfig);
}
} else {
logger.warning(
`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`
);
}
} catch (err) {
errorMessage = err.message;
} finally {
// report on the status of the engine, one way or another!
logger.info(
`Pattern Engine ${engineDiscovery.name}: ${
`Pattern Engine ${engineConfig.extension}: ${
errorMessage ? errorMessage : successMessage
}`
);
}
}
} else {
// Try to load engines! We scan for engines at each path specified above. This
// function is kind of a big deal.
enginesDirectories.forEach(function(engineDirectory) {
const enginesInThisDir = findEngineModulesInDirectory(
engineDirectory.path
);

logger.debug(`Loading engines from ${engineDirectory.displayName}...`);

// find all engine-named things in this directory and try to load them,
// unless it's already been loaded.
enginesInThisDir.forEach(function(engineDiscovery) {
let errorMessage;
const successMessage = 'good to go';

try {
// Give it a try! load 'er up. But not if we already have,
// of course. Also pass the pattern lab config object into
// the engine's closure scope so it can know things about
// things.
if (self[engineDiscovery.name]) {
throw new Error('already loaded, skipping.');
}
self[engineDiscovery.name] = require(engineDiscovery.modulePath);
if (
typeof self[engineDiscovery.name].usePatternLabConfig ===
'function'
) {
self[engineDiscovery.name].usePatternLabConfig(patternLabConfig);
}
if (typeof self[engineDiscovery.name].spawnMeta === 'function') {
self[engineDiscovery.name].spawnMeta(patternLabConfig);
}
} catch (err) {
errorMessage = err.message;
} finally {
// report on the status of the engine, one way or another!
logger.info(
`Pattern Engine ${engineDiscovery.name}: ${
errorMessage ? errorMessage : successMessage
}`
);
}
});
});
});
}

// Complain if for some reason we haven't loaded any engines.
if (Object.keys(self).length === 0) {
Expand Down
15 changes: 15 additions & 0 deletions packages/core/test/util/patternlab-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,21 @@
"density": "compact",
"layout": "horizontal"
},
"engines": {
"mustache": {
"package":"@pattern-lab/engine-mustache",
"fileExtensions": [
"mustache"
]
},
"handlebars": {
"package": "@pattern-lab/engine-handlebars",
"fileExtensions": [
"handlebars",
"hbs"
]
}
},
"uikits": [
{
"name": "uikit-workshop",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@
],
"engines": {
"handlebars": {
"package": "@pattern-lab/engine-handlebars",
"fileExtensions": [
"handlebars",
"hbs"
],
"extend": "helpers/*.js"
}
},
Expand Down
14 changes: 14 additions & 0 deletions packages/development-edition-engine-react/patternlab-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,19 @@
"color": "dark",
"density": "compact",
"layout": "horizontal"
},
"engines": {
"mustache": {
"package":"@pattern-lab/engine-mustache",
"fileExtensions": [
"mustache"
]
},
"handlebars": {
"package": "@pattern-lab/engine-react",
"fileExtensions": [
"jsx"
]
}
}
}
10 changes: 10 additions & 0 deletions packages/development-edition-engine-twig/patternlab-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,17 @@
}
],
"engines": {
"mustache": {
"package":"@pattern-lab/engine-mustache",
"fileExtensions": [
"mustache"
]
},
"twig": {
"package": "@pattern-lab/engine-twig",
"fileExtensions": [
"twig"
],
"namespaces": {
"atoms": "source/_patterns/00-atoms/",
"molecules": "source/_patterns/01-molecules/",
Expand Down
31 changes: 30 additions & 1 deletion packages/docs/src/docs/advanced-config-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,35 @@ Sets the panel name and language for the code tab on the styleguide. Since this

**default**: `mustache`

### engines

An engine is a wrapper around a templating library like Mustache, Handlebars, Twig or others. An engine package
is the bridge between PatternLab and the standalone NPM package supporting the templating language.

`engines` accepts an map of Engine objects. The mandatory properties for each PatternLab engine are:

- `package`: the NodeJS package name. Add the package of the engine as a dependency in `package.json` before you configure it here.
- `fileExtensions`: list of pattern file extensions which will be handled by this pattern engine.

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.

**default**:

```javascript
"engines": {
"mustache": {
"package": "@pattern-lab/engine-mustache",
"extensions": [
"mustache"
],
...
}
}
```

Configuring the engines in the config file was introduced in v5.14. The fallback lookup mode by scanning the
`node_modules` folder is **deprecated** will be removed in v6.

### patternStateCascade

See the [Pattern State Documentation](/docs/using-pattern-states/)
Expand Down Expand Up @@ -336,7 +365,7 @@ Important details:
- 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
- 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.
- `dependencyGraph.json` has moved to the project root rather than `public/` as we should only retain one
- 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:
- 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:
- `<name>`
- `uikit-<name>`
- `@pattern-lab/<name>`
Expand Down
8 changes: 8 additions & 0 deletions packages/edition-node-gulp/patternlab-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@
"density": "compact",
"layout": "horizontal"
},
"engines": {
"mustache": {
"package": "@pattern-lab/engine-mustache",
"fileExtensions": [
"mustache"
]
}
},
"uikits": [
{
"name": "uikit-workshop",
Expand Down
4 changes: 4 additions & 0 deletions packages/edition-node/patternlab-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@
],
"engines": {
"handlebars": {
"package": "@pattern-lab/engine-handlebars",
"fileExtensions": [
"hbs"
],
"extend": "helpers/*.js"
}
}
Expand Down
4 changes: 4 additions & 0 deletions packages/edition-twig/patternlab-config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{
"engines": {
"twig": {
"package": "@pattern-lab/engine-twig-php",
"fileExtensions": [
"twig"
],
"namespaces": [
{
"id": "uikit",
Expand Down
4 changes: 4 additions & 0 deletions packages/starterkit-twig-demo/patternlab-config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{
"engines": {
"twig": {
"package": "@pattern-lab/engine-twig-php",
"fileExtensions": [
"twig"
],
"namespaces": [
{
"id": "atoms",
Expand Down

0 comments on commit 5d376a5

Please sign in to comment.