-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
import and export components (v4.2.0) #40
Changes from all commits
7e93872
35b8c1e
74b2899
668ccfb
79223a3
8ae56c4
6a2a19d
0d8e747
77e550b
13e7843
d78c514
9b4ddab
1636823
023a5eb
76bd25d
a24696b
e161e56
a72da44
f6918ee
79e1499
fd506dd
b38bb47
3b5ccd9
9fd79ff
03daa12
ec47fd9
b7de92b
015bcfa
a2141fa
961b8b0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
// This script contains all the steps for generating the output results. | ||
// This can be triggered by running `npm run build` | ||
// | ||
// A majority of this file uses the UglifyJS API | ||
// https://www.npmjs.com/package/uglify-js | ||
// | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const UglifyJS = require('uglify-js'); | ||
const { version } = require('./package.json'); | ||
|
||
// before we start anything, make sure the output directory exists and is empty | ||
if (!fs.existsSync('output')) { | ||
// if it doesn't exist make it | ||
fs.mkdirSync('output'); | ||
} else { | ||
// if it does, remove all files in the directory | ||
const files = fs.readdirSync('output'); | ||
for (const file of files) { | ||
const filePath = path.join('output', file); | ||
fs.unlinkSync(filePath); | ||
} | ||
} | ||
|
||
// load all source class files (these will be included in all builds) | ||
const classFiles = ['src/TramLite.js', ...fs.readdirSync('src/processors').map((file) => `src/processors/${file}`)]; | ||
const loadedClassFiles = Object.fromEntries( | ||
classFiles.map((filePath) => { | ||
console.log('loading', filePath); | ||
return [filePath, fs.readFileSync(filePath).toString()]; | ||
}), | ||
); | ||
|
||
// load all import/export scripts separately (these are only included in some builds) | ||
console.log('loading', 'src/import-components.js'); | ||
const importComponentClass = { | ||
'src/ImportComponent.js': fs.readFileSync('src/ImportComponent.js').toString(), | ||
}; | ||
console.log('loading', 'src/import-script.js'); | ||
const importScript = { | ||
'src/scripts/import-script.js': fs.readFileSync('src/scripts/import-script.js').toString(), | ||
}; | ||
|
||
// uglify parameters to change the result of each bundle. | ||
// `MODULE` and `INSTALL` are variables that can be found in the class files and | ||
// determine if we should attach listeners for a window or export the class for a JS API. | ||
// `enclose` determines if the code should be wrapped in an IIFE (which prevents | ||
// prevents class definitions from colliding). | ||
const buildConfigs = [ | ||
{ | ||
outputFile: 'output/api.js', | ||
files: loadedClassFiles, | ||
defines: { MODULE: true, INSTALL: false }, | ||
}, | ||
{ | ||
outputFile: 'output/tram-lite.js', | ||
files: loadedClassFiles, | ||
defines: { MODULE: false, INSTALL: true }, | ||
}, | ||
{ | ||
outputFile: 'output/import-components.js', | ||
files: { ...loadedClassFiles, ...importComponentClass, ...importScript }, | ||
defines: { MODULE: false, INSTALL: false }, | ||
enclose: true, | ||
}, | ||
{ | ||
outputFile: 'output/export-dependencies.js', | ||
files: { ...loadedClassFiles, ...importComponentClass }, | ||
defines: { MODULE: false, INSTALL: false }, | ||
}, | ||
]; | ||
|
||
buildConfigs.forEach((config) => { | ||
console.log('building', config.outputFile); | ||
const options = { | ||
compress: { | ||
global_defs: { | ||
APP_VERSION: version, | ||
...config.defines, | ||
}, | ||
}, | ||
enclose: config.enclose, | ||
output: { | ||
comments: 'all', | ||
beautify: true, | ||
}, | ||
}; | ||
const result = UglifyJS.minify(config.files, options); | ||
fs.writeFileSync(config.outputFile, result.code); | ||
}); | ||
|
||
// for each of these, create a minified version | ||
const minifyConfigs = [ | ||
{ inputFile: 'output/api.js', outputFile: 'output/api.min.js' }, | ||
{ inputFile: 'output/tram-lite.js', outputFile: 'output/tram-lite.min.js' }, | ||
{ inputFile: 'output/import-components.js', outputFile: 'output/import-components.min.js' }, | ||
{ inputFile: 'output/export-dependencies.js', outputFile: 'output/export-dependencies.min.js' }, | ||
]; | ||
|
||
minifyConfigs.forEach((config) => { | ||
console.log('minifying', config.outputFile); | ||
const result = UglifyJS.minify(fs.readFileSync(config.inputFile, 'utf8')); | ||
fs.writeFileSync(config.outputFile, result.code); | ||
}); | ||
|
||
// do a simple copy for the export-script (needs no minification) | ||
fs.copyFileSync('src/scripts/export-script.js', 'output/export-components.js'); | ||
|
||
console.log('Tram-Lite build complete!'); |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,6 +44,13 @@ | |
<meta name="twitter:card" content="summary_large_image" /> | ||
<meta name="twitter:image:src" content="https://tram-one.io/tram-lite/preview.png" /> | ||
|
||
<!-- styles --> | ||
<style> | ||
:root { | ||
background: rgb(31, 44, 57); | ||
background: linear-gradient(140deg, rgba(31, 44, 57, 1) 0%, rgba(49, 49, 26, 1) 100%); | ||
} | ||
</style> | ||
Comment on lines
+47
to
+53
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. adding a nice gradient to the background of the main website - including this here so that we always have this (even if the external stylesheet doesn't load). The gradient itself was created with cssgradient.io |
||
<link rel="stylesheet" type="text/css" href="./styles.css" /> | ||
|
||
<!-- highlight.js --> | ||
|
@@ -78,6 +85,7 @@ | |
<side-nav-section> | ||
<a href="#install">Install</a> | ||
<a href="#building-components">Building Components</a> | ||
<a href="#importing-and-exporting">Importing & Exporting</a> | ||
</side-nav-section> | ||
<a>HTML API</a> | ||
<side-nav-section> | ||
|
@@ -110,6 +118,7 @@ | |
></page> | ||
<page id="guiding-principles"><html-import src="./pages/guiding-principles.html"></html-import></page> | ||
<page id="building-components"><html-import src="./pages/guide-building-components.html"></html-import></page> | ||
<page id="importing-and-exporting"><html-import src="./pages/importing-and-exporting.html"></html-import></page> | ||
<page id="projects-and-posts"><html-import src="./pages/projects-and-posts.html"></html-import></page> | ||
<!-- <page id="cheat-sheet"><html-import src="./pages/cheat-sheet.html"></html-import></page> --> | ||
</main> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
<h2>Importing And Exporting Components</h2> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. New documentation for the functionality added in this PR! 📝 |
||
<p> | ||
If you are building a library, there are a few different options when it comes to sharing your components with other | ||
developers. On this page, we document a few different options, and the reasons why you may choose one. | ||
</p> | ||
<p> | ||
Regardless of how you choose to share your components, doing so is a great way to make components easily consumable | ||
among other developers, without requiring Tram-Lite as a core dependency. All methods also allow you to have different | ||
versions of Tram-Lite components in the same project. | ||
</p> | ||
|
||
<h3>Using import-components script</h3> | ||
<p> | ||
The <code>import-components</code> script is a great way to share raw HTML templates without requiring a build step as | ||
part of your project. It also allows developers to selectively choose which elements they would like to import. | ||
|
||
<code-template-html> | ||
<template> | ||
<script src="https://unpkg.com/tram-lite@4/output/import-components.js" tl-components="..."></script> | ||
</template> | ||
</code-template-html> | ||
|
||
The script depends on an attribute <code>tl-components</code>, which is a space separated list of paths to the | ||
components you'd like to import. | ||
</p> | ||
<h4>Parameters</h4> | ||
<p> | ||
The only parameter for <code>import-components.js</code> is the <code>tl-components</code> attribute. It is a space | ||
delimited list of component definition paths. The components should be HTML, and just the definition of the | ||
components, the same as the content inside of a <a href="#tl-definition">tl-definition template tag</a>. | ||
</p> | ||
<h4>Example Importing an HTML Template</h4> | ||
<p> | ||
For example, we might have the following <code>x-button.html</code>. | ||
<code-template-html> | ||
<template> | ||
<x-button> | ||
<button>Hello World</button> | ||
</x-button> | ||
</template> | ||
</code-template-html> | ||
|
||
We could then import and immediately use this component in our HTML page using the | ||
<code>import-components.js</code> script. | ||
|
||
<code-template-html> | ||
<template> | ||
<script src="https://unpkg.com/tram-lite@4/output/import-components.js" tl-components="./x-button.html"></script> | ||
<x-button></x-button> | ||
</template> | ||
</code-template-html> | ||
</p> | ||
<p>This script is also available as a minified script - simply point to <code>import-components.min.js</code>.</p> | ||
|
||
<h3>Using export-components command</h3> | ||
<p> | ||
The <code>export-components</code> CLI tool is a great way to build native javascript if consumers of the library are | ||
using tools to bundle their code, or if you (or your consumers) have a build step. It's also great because it works | ||
with the native script import on the consumer's side. | ||
|
||
<code-template-js> | ||
<template> | ||
<script> | ||
npx tram-lite@4 export-components ... | ||
</script> | ||
</template> | ||
</code-template-js> | ||
|
||
You can pass in any html files you'd like to be bundled, and it will create a javascript file that people can natively | ||
import with a script tag. | ||
</p> | ||
<h4>Parameters</h4> | ||
<p> | ||
<code-template-js> | ||
<template> | ||
<script> | ||
npx tram-lite@4 export-components <components> [--output output-file.js] [--minified] | ||
</script> | ||
</template> | ||
</code-template-js> | ||
Aside from the required components, the command has two optional flags, <code>--output</code> and | ||
<code>--minified</code>. | ||
</p> | ||
<p> | ||
<code>--output</code> (or <code>-o</code>) can be used to set the file name and directory of the resulting javascript. | ||
If this flag is missing, the command will place the file in the current directory, named based on the component files | ||
passed in. | ||
</p> | ||
<p> | ||
<code>--minified</code> (or <code>-m</code>) can be used to import the minified Tram-Lite code as part of your export. | ||
This should reduce the total size of the exported components. | ||
</p> | ||
<h4>Example Exporting an HTML Template to Javascript</h4> | ||
<p> | ||
Similar to the example above, we start with a component definition in an <code>x-button.html</code>. | ||
<code-template-html> | ||
<template> | ||
<x-button> | ||
<button>Hello World</button> | ||
</x-button> | ||
</template> | ||
</code-template-html> | ||
|
||
Then we can run the command to export this component to javascript. | ||
<code-template-js> | ||
<template> | ||
<script> | ||
npx tram-lite@4 export-components x-button.html | ||
</script> | ||
</template> | ||
</code-template-js> | ||
|
||
This will create an <code>x-button.js</code> file locally. We can then import that file using a normal script tag. | ||
<code-template-html> | ||
<template> | ||
<script src="x-button.js"></script> | ||
<x-button></x-button> | ||
</template> | ||
</code-template-html> | ||
</p> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
node output/export-components.js examples/components/ex-progressbar.html examples/components/ex-temperature.html examples/components/ex-container.html examples/components/ex-colorpicker.html -o examples/components/example-components.js | ||
node output/export-components.js examples/components/ex-colorpicker.html -o examples/components/ex-colorpicker.js | ||
Comment on lines
+1
to
+2
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right now, this is just a shell script, but we should migrate this with a JS API (separate issue #41) |
||
node output/export-components.js examples/components/ex-todolist.html -o examples/components/ex-todolist.js -m |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<ex-colorpicker width="100px"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a copy-paste of the inline colorpicker example. Some thinking should happen around making this more consistent (see #42) |
||
<style> | ||
svg { | ||
display: block; | ||
} | ||
rect { | ||
fill: oklch(70% 0.1 ${'hue'}); | ||
} | ||
</style> | ||
<input id="hue-range-input" type="range" tl-controlled tl-hostattr="hue" tl-trigger="input" min="0" max="360" /> | ||
<input id="hue-text-input" type="text" placeholder="hue value" tl-controlled tl-hostattr="hue" /> | ||
<svg viewbox="0 0 100 100" width="${'width'}"> | ||
<rect width="100" height="100" /> | ||
</svg> | ||
</ex-colorpicker> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this new
build.js
replaces the set of scripts that were in thepackage.json
. This is a more organized way to bundle and expose all the different scripts that we need, allows us to write comments, and have more consistent behavior across all the generated scripts.Candidly, this is slightly more error prone, compared to the CLI interface (which is better documented), but all in all, worth the migration.