Skip to content

Commit

Permalink
Exclude unused components in js export (v5.3.0)
Browse files Browse the repository at this point in the history
  • Loading branch information
JRJurman committed Jan 13, 2024
1 parent d1d32fa commit 27496d7
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 44 deletions.
57 changes: 30 additions & 27 deletions build.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,32 @@ 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);
const outputDirectories = ['output', 'output/export', 'output/export/processors'];
outputDirectories.forEach((directory) => {
if (!fs.existsSync(directory)) {
// if it doesn't exist make it
fs.mkdirSync(directory);
} else {
// if it does, remove all files in the directory
const files = fs.readdirSync(directory);
for (const file of files) {
const filePath = path.join(directory, file);
try {
fs.unlinkSync(filePath);
} catch {
// if we tried to delete a directory, this will blow up
// but it's actually fine...
}
}
}
}
});

// load all source class files (these will be included in all builds)
// ORDER IS IMPORTANT! We need ComponentDefinition to be last, so that
// shadow root processors exist by the time we start processing templates
const classFiles = [
'src/TramLite.js',
'src/processors/ComponentEffect.js',
'src/processors/ControlledInput.js',
'src/processors/AttrBroadcaster.js',
'src/processors/EventRebroadcaster.js',
'src/processors/ExternalScript.js',
'src/processors/ContextConsumer.js',
'src/ComponentDefinition.js',
];
const processors = fs.readdirSync('src/processors').map((file) => `src/processors/${file}`);
const classFiles = ['src/TramLite.js', ...processors, 'src/ComponentDefinition.js'];

const loadedClassFiles = Object.fromEntries(
classFiles.map((filePath) => {
console.log('loading', filePath);
Expand Down Expand Up @@ -67,11 +68,6 @@ const buildConfigs = [
defines: { INSTALL: false },
enclose: true,
},
{
outputFile: 'output/export-dependencies.js',
files: { ...loadedClassFiles, ...importComponentClass },
defines: { INSTALL: false },
},
];

buildConfigs.forEach((config) => {
Expand All @@ -97,12 +93,19 @@ buildConfigs.forEach((config) => {
const minifyConfigs = [
{ 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' },
// build files for use with the export-components script
...classFiles.map((classFile) => ({
inputFile: classFile,
outputFile: classFile.replace('src', 'output/export').replace('.js', '.min.js'),
})),
{ inputFile: 'src/ImportComponent.js', outputFile: 'output/export/ImportComponent.min.js' },
];

minifyConfigs.forEach((config) => {
console.log('minifying', config.outputFile);
const result = UglifyJS.minify(fs.readFileSync(config.inputFile, 'utf8'));
const result = UglifyJS.minify(fs.readFileSync(config.inputFile, 'utf8'), {
compress: { global_defs: { APP_VERSION: version, INSTALL: false } },
});
fs.writeFileSync(config.outputFile, result.code);
});

Expand Down
9 changes: 2 additions & 7 deletions docs/pages/importing-and-exporting.html
Original file line number Diff line number Diff line change
Expand Up @@ -74,22 +74,17 @@ <h4>Parameters</h4>
<code-template-js>
<template>
<script>
npx tram-lite@5 export-components <components> [--output output-file.js] [--minified]
npx tram-lite@5 export-components <components> [--output output-file.js]
</script>
</template>
</code-template-js>
Aside from the required components, the command has two optional flags, <code>--output</code> and
<code>--minified</code>.
Aside from the required components, the command has one optional flag, <code>--output</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>.
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tram-lite",
"version": "5.2.0",
"version": "5.3.0",
"description": "💡 HTML library for building and enhancing web-components",
"homepage": "https://tram-one.io/tram-lite/",
"repository": "https://github.com/Tram-One/tram-lite",
Expand Down
40 changes: 33 additions & 7 deletions src/scripts/export-script.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
const fs = require('fs');
const path = require('path');

// check to see if we should use the minified flag for external dependencies
const useMinified = process.argv.includes('-m') || process.argv.includes('--minified');

// check to see if there is a predefined output filename (otherwise we will try to generate one)
const outputFlagIndex = process.argv.findIndex((arg) => arg === '-o' || arg === '--output');
const customOutputFile = outputFlagIndex !== -1 ? process.argv[outputFlagIndex + 1] : null;
Expand All @@ -26,11 +23,40 @@ if (filePaths.length === 0) {
console.log('processing', filePaths, 'for export');
const componentDefinitions = filePaths.map((filePath) => fs.readFileSync(filePath, 'utf8'));

const tramLiteExportDependenciesPath = useMinified
? path.join(__dirname, './export-dependencies.min.js')
: path.join(__dirname, './export-dependencies.js');
// load the core Tram-Lite library and classes (which are always needed)
const coreFiles = [
'./export/TramLite.min.js',
'./export/ComponentDefinition.min.js',
'./export/ImportComponent.min.js',
].map((filePath) => fs.readFileSync(path.join(__dirname, filePath)).toString());

// load all shadow root processors
const processorFiles = fs
.readdirSync(path.join(__dirname, './export/processors'))
.map((file) => `./export/processors/${file}`)
.map((filePath) => fs.readFileSync(path.join(__dirname, filePath)).toString());

// determine if we need these processors for these components
// (note, this is a very weak regex check, and not using proper CSS or static analysis)
const processorFilesToInclude = processorFiles.filter((processorContent) => {
// the following regex matches on calls to appendShadowRootProcessor
// it specifically captures the first parameter (a CSS selector), and
// parses out the parameter as a whole, and then the text inside `[...]`
const matches = processorContent.match(/TramLite\.appendShadowRootProcessor\(\"([^\[\,]*(\[?(.+)\])?[^\]\,]*)\"/);

if (!matches) {
console.log(processorContent);
}

// get the last most match (the most specific)
const keySelector = [matches[1], matches[2], matches[3]].filter((selector) => selector != undefined).at(-1);

// see if any of our component definitions match with this selector
return componentDefinitions.some((template) => template.match(keySelector));
});

const tramLiteExportDepenedencies = [...coreFiles, ...processorFilesToInclude].join('');

const tramLiteExportDepenedencies = fs.readFileSync(tramLiteExportDependenciesPath).toString();
const templateAndLoadCode = componentDefinitions
.map((componentCode) => {
// update the component code, in case it also uses ``, we'll need to escape them
Expand Down

0 comments on commit 27496d7

Please sign in to comment.