Skip to content

Commit

Permalink
Merge pull request #784 from idyll-lang/compile-user-components
Browse files Browse the repository at this point in the history
add functionality to compile JSX user components
  • Loading branch information
mathisonian authored Apr 15, 2022
2 parents 66071c8 + c166faa commit 11cf577
Show file tree
Hide file tree
Showing 50 changed files with 160 additions and 436 deletions.
2 changes: 1 addition & 1 deletion packages/idyll-cli/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,9 @@ const idyll = (options = {}, cb) => {
temp: '.idyll',
template: join(__dirname, 'client', '_index.html'),
transform: [],
transformComponents: false,
compiler: {},
compileLibs: false,
compileUserComponents: true,
env: commandLineOptions.env
},
options
Expand Down
9 changes: 0 additions & 9 deletions packages/idyll-cli/src/node-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ module.exports = (paths, opts) => {
debug('Reading components from directories:', transformFolders);

const originalLoad = Module._load;
const isWindows = os.platform().includes('win');
Module._load = function(path) {
switch (path) {
case 'react':
Expand All @@ -25,12 +24,4 @@ module.exports = (paths, opts) => {
return originalLoad.apply(Module, arguments);
}
};

if (opts.transformComponents) {
require('@babel/register')({
presets: ['@babel/env', '@babel/preset-react'],
babelrc: false,
only: isWindows ? undefined : transformFolders
});
}
};
37 changes: 37 additions & 0 deletions packages/idyll-cli/src/pipeline/compile-user-components.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const fs = require('fs');
const { readdir, writeFile } = fs.promises;
const { ensureDir, pathExists } = require('fs-extra');
const path = require('path');
const babel = require('@babel/core');

module.exports = async paths => {
let componentDirIndex = 0;
const tempComponentDir = path.join(paths.TMP_DIR, 'components');
await ensureDir(tempComponentDir);
for (const dir of paths.COMPONENT_DIRS) {
const hasPath = await pathExists(dir);
if (!hasPath) {
continue;
}
const tempComponentSubdir = path.join(
tempComponentDir,
`${componentDirIndex}`
);
await ensureDir(tempComponentSubdir);
const files = await readdir(dir);
for (const file of files) {
const { code } = await babel.transformFileAsync(path.join(dir, file), {
presets: ['@babel/preset-react']
});
await writeFile(
path.join(tempComponentSubdir, path.basename(file)),
code,
'utf-8'
);
}
paths.COMPONENT_DIRS[componentDirIndex] = tempComponentSubdir;
componentDirIndex++;
}

return paths;
};
2 changes: 1 addition & 1 deletion packages/idyll-cli/src/pipeline/create-js-entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ var ast = ${JSON.stringify(ast)};
${components
.map(([k, p], i) => {
return `import _component_${i} from '${p}'`;
return `import _component_${i} from '${p.replace(/\\/g, '\\\\')}'`;
})
.join('\n')}
Expand Down
8 changes: 6 additions & 2 deletions packages/idyll-cli/src/pipeline/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const {
} = require('./parse');
const bundleJS = require('./bundle-js');
const errors = require('../errors');
const compileUserComponents = require('./compile-user-components');

let output;

Expand All @@ -29,6 +30,10 @@ const build = async (opts, paths, resolvers) => {
}
}

if (opts.compileUserComponents) {
paths = await compileUserComponents(paths);
}

const ast =
opts.ast ||
(await compile(opts.inputString, {
Expand All @@ -39,7 +44,6 @@ const build = async (opts, paths, resolvers) => {

const template = fs.readFileSync(paths.HTML_TEMPLATE_FILE, 'utf8');

/* Change here */
resolvers.set('components', new ComponentResolver(opts, paths));

let nameArray = [];
Expand All @@ -54,7 +58,7 @@ const build = async (opts, paths, resolvers) => {
const uniqueComponents = Array.from(new Set(nameArray));
const components = uniqueComponents.reduce((acc, name) => {
let resolved = resolvers.get('components').resolve(name);
if (resolved) acc[paramCase(name)] = resolved;
if (resolved) acc[paramCase(name)] = resolved.replace(/\\/g, '\\\\');
return acc;
}, {});

Expand Down
8 changes: 6 additions & 2 deletions packages/idyll-cli/src/pipeline/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const path = require('path');
const mustache = require('mustache');
const resolve = require('resolve');
const slash = require('slash');
const os = require('os');

const {
getProperty,
Expand Down Expand Up @@ -169,16 +170,19 @@ exports.getBaseHTML = (ast, template, opts) => {

exports.getHTML = async (paths, ast, _components, datasets, template, opts) => {
const components = {};
const isWindows = os.platform().includes('win');

for (key of Object.keys(_components)) {
// .forEach(key => {
delete require.cache[require.resolve(_components[key])];

try {
components[key] = require(_components[key]);
} catch (e) {
// console.log(e);
try {
components[key] = await import(_components[key]);
components[key] = await import(isWindows
? `file://${_components[key].replace(/\\/g, '\\\\')}`
: _components[key]);
} catch (er) {
console.warn(
`Could not import component ${key} for server-side rendering.`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
const React = require('react');
import React from 'react';

class PascalComponent extends React.PureComponent {
render() {
const {hasError, updateProps, idyll, ...props} = this.props;
const { hasError, updateProps, idyll, ...props } = this.props;

return (
<div {...props}>
This is a custom component
</div>
);
return <div {...props}>This is a custom component</div>;
}
}

module.exports = PascalComponent;
export default PascalComponent;
Original file line number Diff line number Diff line change
@@ -1,25 +1,17 @@
const React = require('react');
import React from 'react';

class CustomComponent extends React.PureComponent {
render() {
const {hasError, updateProps, idyll, ...props} = this.props;
return (
<div {...props}>
This is a custom component
</div>
);
const { hasError, updateProps, idyll, ...props } = this.props;
return <div {...props}>This is a custom component</div>;
}
}

module.exports = CustomComponent;
export default CustomComponent;

module.exports.IndexedComponent = class extends React.PureComponent {
CustomComponent.IndexedComponent = class extends React.PureComponent {
render() {
const {hasError, updateProps, idyll, ...props} = this.props;
return (
<div {...props}>
This is another custom component
</div>
);
const { hasError, updateProps, idyll, ...props } = this.props;
return <div {...props}>This is another custom component</div>;
}
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const React = require('react');
import React from 'react';

module.exports = () => {
return <div>Let's put the fun back in functional!</div>
}
export default () => {
return <div>Let's put the fun back in functional!</div>;
};
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
const React = require('react');
import React from 'react';

export default () =>
export default () => (
<div>
This is some text
<button>And a button</button>
Then some more text
</div>
);
1 change: 1 addition & 0 deletions packages/idyll-cli/test/basic-project/src/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"start": "idyll index.idl --watch --css styles.css --layout centered --theme github --spellcheck",
"build": "idyll index.idl --layout centered --theme ./custom-theme.css --css styles.css"
},
"type": "module",
"idyll": {
"alias": {
"PackageJsonComponentTest": "CustomComponent"
Expand Down
3 changes: 1 addition & 2 deletions packages/idyll-cli/test/basic-project/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ before(function(done) {
css: join(PROJECT_DIR, 'styles.css'),
googleFonts: ['Hanalei Fill'],
favicon: 'static/favicon.ico',
transformComponents: true,
compiler: {
spellcheck: false
},
Expand Down Expand Up @@ -91,7 +90,7 @@ it('options work as expected', () => {
defaultComponents: dirname(require.resolve('idyll-components')),
temp: '.idyll',
template: resolve(join(__dirname, '/../../src/client/_index.html')),
transformComponents: true,
compileUserComponents: true,
datasets: join(PROJECT_DIR, 'data'),
static: 'static',
staticOutputDir: 'static',
Expand Down
1 change: 0 additions & 1 deletion packages/idyll-cli/test/batteries-included/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ describe('batteries-included project', function() {
idyll({
inputFile: join(PROJECT_DIR, 'index.idl'),
output: PROJECT_BUILD_DIR,
transformComponents: true,
compiler: {
spellcheck: false
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const React = require('react');
import React from 'react';

class PascalComponent extends React.PureComponent {
render() {
Expand All @@ -8,4 +8,4 @@ class PascalComponent extends React.PureComponent {
}
}

module.exports = PascalComponent;
export default PascalComponent;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const React = require('react');
import React from 'react';

class CustomComponent extends React.PureComponent {
render() {
Expand All @@ -7,11 +7,13 @@ class CustomComponent extends React.PureComponent {
}
}

module.exports = CustomComponent;
export default CustomComponent;

module.exports.IndexedComponent = class extends React.PureComponent {
class IndexedComponent extends React.PureComponent {
render() {
const { hasError, updateProps, idyll, ...props } = this.props;
return <div {...props}>This is another custom component</div>;
}
};
}

export { IndexedComponent };
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const React = require('react');
import React from 'react';

module.exports = () => {
export default () => {
return <div>Let's put the fun back in functional!</div>;
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const React = require('react');
import React from 'react';

export default () => (
<div>
Expand Down
1 change: 1 addition & 0 deletions packages/idyll-cli/test/custom-ast/src/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"start": "idyll index.idl --watch --css styles.css --layout centered --theme github --spellcheck",
"build": "idyll index.idl --layout centered --theme ./custom-theme.css --css styles.css"
},
"type": "module",
"idyll": {
"alias": {
"PackageJsonComponentTest": "CustomComponent"
Expand Down
3 changes: 1 addition & 2 deletions packages/idyll-cli/test/custom-ast/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ before(function(done) {
css: join(PROJECT_DIR, 'styles.css'),
googleFonts: ['Hanalei Fill'],
favicon: 'static/favicon.ico',
transformComponents: true,
compiler: {
spellcheck: false
},
Expand Down Expand Up @@ -197,7 +196,7 @@ it('options work as expected', () => {
static: 'static',
staticOutputDir: 'static',
transform: [],
transformComponents: true,
compileUserComponents: true,
port: 3000,
googleFonts: ['Hanalei Fill'],
outputCSS: 'idyll_styles.css',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const React = require('react');
import React from 'react';

class PascalComponent extends React.PureComponent {
render() {
Expand All @@ -8,4 +8,4 @@ class PascalComponent extends React.PureComponent {
}
}

module.exports = PascalComponent;
export default PascalComponent;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const React = require('react');
import React from 'react';

class CustomComponent extends React.PureComponent {
render() {
Expand All @@ -7,9 +7,9 @@ class CustomComponent extends React.PureComponent {
}
}

module.exports = CustomComponent;
export default CustomComponent;

module.exports.IndexedComponent = class extends React.PureComponent {
CustomComponent.IndexedComponent = class extends React.PureComponent {
render() {
const { hasError, updateProps, idyll, ...props } = this.props;
return <div {...props}>This is another custom component</div>;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const React = require('react');
import React from 'react';

module.exports = () => {
export default () => {
return <div>Let's put the fun back in functional!</div>;
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const React = require('react');
import React from 'react';

export default () => (
<div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"scripts": {
"start": "idyll index.idl --watch --css styles.css --layout centered --theme github --spellcheck"
},
"type": "module",
"idyll": [
[
"default-env",
Expand Down
Loading

0 comments on commit 11cf577

Please sign in to comment.