summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorGravatar Matthew Phillips <matthew@matthewphillips.info> 2021-03-31 16:46:09 -0400
committerGravatar GitHub <noreply@github.com> 2021-03-31 16:46:09 -0400
commitd5b15a385153915cad7dbffd0d8893c39059c1ed (patch)
tree769240e3f6e52c31639f0500d97b87e45f202a6a /src/compiler
parentd9084ff4ad9e25577846d3eb53046c2f0066097f (diff)
downloadastro-d5b15a385153915cad7dbffd0d8893c39059c1ed.tar.gz
astro-d5b15a385153915cad7dbffd0d8893c39059c1ed.tar.zst
astro-d5b15a385153915cad7dbffd0d8893c39059c1ed.zip
Support for custom elements (#45)
* Support for custom elements Now you can use custom elements like so in Astro components: ```html <script type="module" src="./datepicker.js"> <date-picker></date-picker> ``` These will be resolve relative to the current astro component. In the build these modules are run through the same bundle/minify process as components. * Remove component from public * Formatting * Disable empty fn rule
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/optimize/index.ts10
-rw-r--r--src/compiler/optimize/module-scripts.ts42
2 files changed, 49 insertions, 3 deletions
diff --git a/src/compiler/optimize/index.ts b/src/compiler/optimize/index.ts
index d86ce3c24..e73c93c7c 100644
--- a/src/compiler/optimize/index.ts
+++ b/src/compiler/optimize/index.ts
@@ -1,10 +1,13 @@
-import { walk } from 'estree-walker';
import type { Ast, TemplateNode } from '../../parser/interfaces';
-import { NodeVisitor, Optimizer, VisitorFn } from '../../@types/optimizer';
+import type { CompileOptions } from '../../@types/compiler';
+import type { NodeVisitor, Optimizer, VisitorFn } from '../../@types/optimizer';
+
+import { walk } from 'estree-walker';
// Optimizers
import optimizeStyles from './styles.js';
import optimizeDoctype from './doctype.js';
+import optimizeModuleScripts from './module-scripts.js';
interface VisitorCollection {
enter: Map<string, VisitorFn[]>;
@@ -67,6 +70,7 @@ function walkAstWithVisitors(tmpl: TemplateNode, collection: VisitorCollection)
}
interface OptimizeOptions {
+ compileOptions: CompileOptions;
filename: string;
fileID: string;
}
@@ -76,7 +80,7 @@ export async function optimize(ast: Ast, opts: OptimizeOptions) {
const cssVisitors = createVisitorCollection();
const finalizers: Array<() => Promise<void>> = [];
- const optimizers = [optimizeStyles(opts), optimizeDoctype(opts)];
+ const optimizers = [optimizeStyles(opts), optimizeDoctype(opts), optimizeModuleScripts(opts)];
for (const optimizer of optimizers) {
collectVisitors(optimizer, htmlVisitors, cssVisitors, finalizers);
diff --git a/src/compiler/optimize/module-scripts.ts b/src/compiler/optimize/module-scripts.ts
new file mode 100644
index 000000000..713747fcb
--- /dev/null
+++ b/src/compiler/optimize/module-scripts.ts
@@ -0,0 +1,42 @@
+import type { Optimizer } from '../../@types/optimizer';
+import type { CompileOptions } from '../../@types/compiler';
+
+import path from 'path';
+import { getAttrValue, setAttrValue } from '../../ast.js';
+
+export default function ({ compileOptions, filename }: { compileOptions: CompileOptions; filename: string; fileID: string }): Optimizer {
+ const { astroConfig } = compileOptions;
+ const { astroRoot } = astroConfig;
+ const fileUrl = new URL(`file://${filename}`);
+
+ return {
+ visitors: {
+ html: {
+ Element: {
+ enter(node) {
+ let name = node.name;
+ if (name !== 'script') {
+ return;
+ }
+
+ let type = getAttrValue(node.attributes, 'type');
+ if (type !== 'module') {
+ return;
+ }
+
+ let src = getAttrValue(node.attributes, 'src');
+ if (!src || !src.startsWith('.')) {
+ return;
+ }
+
+ const srcUrl = new URL(src, fileUrl);
+ const fromAstroRoot = path.posix.relative(astroRoot.pathname, srcUrl.pathname);
+ const absoluteUrl = `/_astro/${fromAstroRoot}`;
+ setAttrValue(node.attributes, 'src', absoluteUrl);
+ },
+ },
+ },
+ },
+ async finalize() {},
+ };
+}