Merge branch 'main' into merge-x

This commit is contained in:
Michael Rawlings 2024-01-09 17:50:14 -05:00
commit d7ff0e1cfe
840 changed files with 11712 additions and 7472 deletions

View File

@ -1,5 +1,6 @@
{
"all": true,
"excludeAfterRemap": true,
"parserPlugins": ["objectRestSpread", "typescript"],
"reporter": ["text-summary", "lcov"],
"include": [

View File

@ -1,15 +1,11 @@
*.min.js
*.html.js
*.marko.js
*actual*
*expected*
.cache/
.nyc_output/
node_modules/
coverage/
*dist/
*generated/
~vdom.skip
**/test/**/input.js
.vscode
__snapshots__
!packages/marko/src/node_modules
.cache
.vscode
*.marko.js
**/test/**/input.js
*actual*
*dist/
*expected*
coverage
node_modules

View File

@ -1,28 +1,42 @@
{
"$schema": "https://json.schemastore.org/eslintrc.json",
"root": true,
"extends": ["eslint:recommended", "prettier"],
"extends": ["eslint:recommended", "plugin:import/recommended", "prettier"],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module",
"impliedStrict": true,
"ecmaFeatures": {
"jsx": false
}
"impliedStrict": true
},
"globals": {
"AggregateError": true
"settings": {
"import/resolver": {
"node": true,
"typescript": true
}
},
"env": {
"node": true,
"mocha": true,
"es2020": true,
"es2024": true,
"browser": true
},
"rules": {
"sort-imports": [
"import/namespace": "off",
"import/order": [
"error",
{
"allowSeparatedGroups": true,
"ignoreDeclarationSort": true
"groups": [
["builtin"],
["external"],
["internal"],
"parent",
"sibling",
"index"
],
"alphabetize": {
"order": "asc",
"orderImportKind": "asc",
"caseInsensitive": true
}
}
]
},
@ -32,18 +46,20 @@
"parser": "@typescript-eslint/parser",
"extends": [
"eslint:recommended",
"plugin:import/typescript",
"plugin:@typescript-eslint/recommended",
"plugin:import/recommended",
"plugin:import/typescript",
"prettier"
],
"rules": {
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-duplicate-enum-values": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-empty-interface": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/no-namespace": "off"
"@typescript-eslint/no-namespace": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-var-requires": "off"
}
}
]

1
.gitattributes vendored
View File

@ -1 +1,2 @@
package-lock.json -diff
packages/marko/src/node_modules/** linguist-generated=false

View File

@ -19,18 +19,22 @@ jobs:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
- name: Use node
uses: actions/setup-node@v3
with:
node-version: 16
node-version: 20
cache: npm
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Format Code
run: npm run format
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v4
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "[ci] format"
commit_user_name: "github-actions[bot]"
@ -46,7 +50,7 @@ jobs:
node: [16, 18, 20]
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Use node@${{ matrix.node }}
uses: actions/setup-node@v3
with:
@ -57,18 +61,18 @@ jobs:
- name: Run tests
run: npm run ci:test
- name: Report code coverage
uses: codecov/codecov-action@v2
uses: codecov/codecov-action@v3
release:
runs-on: ubuntu-latest
needs: [format, test]
if: "${{ github.repository_owner == 'marko-js' && github.event_name == 'push' }}"
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: 16
node-version: 20
cache: npm
- name: Install dependencies
run: npm ci
@ -77,7 +81,7 @@ jobs:
uses: changesets/action@v1
with:
version: npm run version
publish: npm run publish
publish: npm run release
commit: "[ci] release"
title: "[ci] release"
env:

9
.lintstagedrc.json Normal file
View File

@ -0,0 +1,9 @@
{
"$schema": "https://json.schemastore.org/lintstagedrc.schema.json",
"*.{ts,js}": ["eslint --fix", "prettier --write --with-node-modules"],
"*.{json,md,css}": ["prettier --write --with-node-modules"],
"./package.json": [
"prettier --write --with-node-modules",
"sort-package-json --quiet"
]
}

View File

@ -1,31 +1,17 @@
# minfied
*.min.js
# tests
__snapshots__
!packages/marko/src/node_modules
.cache
.nvm
.sizes.json
.vscode
*actual*
*expected*
input.*
__snapshots__
# generated
dist/
*.marko.js
*.html.js
*.xml.js
*.generated.js
.nyc_output
.cache/
coverage
.sizes.json
~*
# controlled by npm's formatter
CHANGELOG.md
coverage
dist
input.*
node_modules
node_modules
package-lock.json
package.json
# controlled by lerna
CHANGELOG.md
lerna.json
# editor
.vscode

View File

@ -1,10 +0,0 @@
{
"overrides": [
{
"files": "*rc",
"options": {
"parser": "json"
}
}
]
}

View File

@ -7,27 +7,27 @@
{
"name": "*",
"total": {
"min": 13300,
"gzip": 5726,
"brotli": 5193
"min": 13292,
"gzip": 5720,
"brotli": 5186
}
},
{
"name": "counter",
"user": {
"min": 351,
"gzip": 278,
"brotli": 240
"gzip": 279,
"brotli": 241
},
"runtime": {
"min": 3957,
"gzip": 1845,
"brotli": 1651
"min": 4031,
"gzip": 1884,
"brotli": 1685
},
"total": {
"min": 4308,
"gzip": 2123,
"brotli": 1891
"min": 4382,
"gzip": 2163,
"brotli": 1926
}
},
{
@ -35,17 +35,17 @@
"user": {
"min": 204,
"gzip": 180,
"brotli": 159
"brotli": 153
},
"runtime": {
"min": 2478,
"gzip": 1292,
"brotli": 1153
"min": 2593,
"gzip": 1350,
"brotli": 1213
},
"total": {
"min": 2682,
"gzip": 1472,
"brotli": 1312
"min": 2797,
"gzip": 1530,
"brotli": 1366
}
},
{
@ -53,35 +53,35 @@
"user": {
"min": 1216,
"gzip": 702,
"brotli": 638
"brotli": 636
},
"runtime": {
"min": 7467,
"gzip": 3451,
"brotli": 3123
"min": 7459,
"gzip": 3446,
"brotli": 3116
},
"total": {
"min": 8683,
"gzip": 4153,
"brotli": 3761
"min": 8675,
"gzip": 4148,
"brotli": 3752
}
},
{
"name": "comments 💧",
"user": {
"min": 988,
"gzip": 589,
"brotli": 545
"gzip": 592,
"brotli": 549
},
"runtime": {
"min": 7988,
"gzip": 3689,
"min": 7980,
"gzip": 3683,
"brotli": 3339
},
"total": {
"min": 8976,
"gzip": 4278,
"brotli": 3884
"min": 8968,
"gzip": 4275,
"brotli": 3888
}
}
]

View File

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright 2020 eBay Inc. and contributors
Copyright 2024 eBay Inc. and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -6,7 +6,7 @@ module.exports = (api) => ({
{
loose: true,
targets: {
node: "16",
node: "18",
},
},
],

View File

@ -1,19 +0,0 @@
const escape = require("shell-quote").quote;
module.exports = {
"*.{json,css,md}": escapeFileNames(["prettier --write", "git add"]),
"*.{js,ts}": escapeFileNames(["eslint --fix", "prettier --write", "git add"]),
};
function escapeFileNames(commands) {
return (filenames) => {
const allFiles = filenames.join(" ");
const allFilesEscaped = filenames
.map((filename) => `"${escape([filename]).replace(/\\@/g, "@")}"`)
.join(" ");
return commands.map(
(command) =>
`${command} ${command === "eslint" ? allFiles : allFilesEscaped}`
);
};
}

7877
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -9,14 +9,13 @@
"build:sizes": "npm run build --ws && node -r ~ts scripts/sizes.ts",
"build:types": "npm run build:types --ws --if-present && tsc -b tsconfig.build.json",
"change": "changeset add",
"ci:report": "c8 report --reporter=text-lcov > coverage.lcov && codecov",
"ci:test": "cross-env NODE_OPTIONS=\"--max-old-space-size=4096\" MARKO_DEBUG=1 c8 npm test",
"format": "npm run lint:eslint -- --fix && npm run lint:prettier -- --write && sort-package-json './{,packages/*/}package.json' --quiet",
"lint": "npm run lint:eslint && npm run lint:prettier -- -l",
"lint:eslint": "eslint -f visualstudio .",
"lint:prettier": "prettier \"./**/*{.ts,.js,.json,.md,.yml}\"",
"lint:prettier": "prettier \"./**/*{.ts,.js,.json,.md,.yml}\" --with-node-modules",
"prepare": "husky install",
"publish": "ENTRY=main:npm npm run set-entry && npm run build && changeset publish && ENTRY=main:dev npm run set-entry && npm ci",
"release": "ENTRY=main:npm npm run set-entry && npm run build && changeset publish && ENTRY=main:dev npm run set-entry && npm ci",
"report": "open ./coverage/lcov-report/index.html",
"set-entry": "npm exec --ws -c 'dot-json package.json main $(dot-json package.json $ENTRY)'",
"test": "mocha",
@ -24,57 +23,55 @@
"version": "changeset version && npm i --package-lock-only"
},
"devDependencies": {
"@babel/cli": "^7.16.0",
"@babel/core": "^7.16.0",
"@babel/plugin-transform-export-namespace-from": "^7.22.5",
"@babel/plugin-transform-modules-commonjs": "^7.22.5",
"@babel/plugin-transform-runtime": "^7.16.0",
"@babel/preset-env": "^7.16.0",
"@babel/preset-typescript": "^7.22.5",
"@babel/register": "^7.16.0",
"@changesets/changelog-github": "^0.4.8",
"@changesets/cli": "^2.26.0",
"@ebay/browserslist-config": "^1.2.0",
"@rollup/plugin-terser": "^0.4.3",
"@rollup/plugin-virtual": "^3.0.1",
"@types/babel__code-frame": "^7.0.3",
"@types/babel__traverse": "^7.14.2",
"@types/jsdom": "^21.1.1",
"@types/mocha": "^10.0.1",
"@types/node": "^20.3.1",
"@typescript-eslint/eslint-plugin": "^5.59.11",
"@typescript-eslint/parser": "^5.59.11",
"~ts": "file:scripts/babel-register.js",
"@babel/cli": "^7.23.4",
"@babel/core": "^7.23.7",
"@babel/plugin-transform-modules-commonjs": "^7.23.3",
"@babel/plugin-transform-runtime": "^7.23.7",
"@babel/preset-env": "^7.23.8",
"@babel/preset-typescript": "^7.23.3",
"@babel/register": "^7.23.7",
"@changesets/changelog-github": "^0.5.0",
"@changesets/cli": "^2.27.1",
"@ebay/browserslist-config": "^2.7.0",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-virtual": "^3.0.2",
"@types/babel__code-frame": "^7.0.6",
"@types/babel__traverse": "^7.20.5",
"@types/jsdom": "^21.1.6",
"@types/mocha": "^10.0.6",
"@types/node": "^20.10.8",
"@typescript-eslint/eslint-plugin": "^6.18.1",
"@typescript-eslint/parser": "^6.18.1",
"babel-plugin-minprops": "^2.0.1",
"bluebird": "^3.7.2",
"c8": "^8.0.0",
"chai": "^4.3.4",
"c8": "^9.0.0",
"chai": "^4.4.0",
"cross-env": "^7.0.3",
"diffable-html": "^4.0.0",
"dot-json": "^1.2.2",
"esbuild": "^0.18.2",
"eslint": "^8.49.0",
"eslint-config-prettier": "^9.0.0",
"eslint-import-resolver-typescript": "^3.5.5",
"express": "^4.17.1",
"husky": "^8.0.0",
"it-fails": "^1.0.5",
"jsdom": "^19.0.0",
"jsdom-context-require": "^4.0.4",
"dot-json": "^1.3.0",
"esbuild": "^0.19.11",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-import-resolver-typescript": "^3.6.1",
"express": "^4.18.2",
"husky": "^8.0.3",
"it-fails": "^1.0.7",
"jsdom": "^23.2.0",
"jsdom-context-require": "^4.0.9",
"kleur": "^4.1.5",
"lint-staged": "^10.5.4",
"mocha": "^8.3.2",
"mocha-autotest": "^1.1.0",
"lint-staged": "^15.2.0",
"mocha": "^10.2.0",
"mocha-autotest": "^1.1.2",
"mocha-snap": "^5.0.0",
"prettier": "^2.8.8",
"pretty-format": "^29.5.0",
"rollup": "^3.25.1",
"shell-quote": "^1.7.2",
"sort-package-json": "^2.4.1",
"prettier": "^3.1.1",
"pretty-format": "^29.7.0",
"rollup": "^4.9.4",
"sort-package-json": "^2.6.0",
"table": "^6.8.1",
"through": "^2.3.8",
"through2": "^4.0.2",
"tiny-glob": "^0.2.9",
"typescript": "^5.1.3"
"typescript": "^5.3.3",
"~ts": "file:scripts/babel-register.js"
}
}

View File

@ -1,5 +1,41 @@
# Change Log
## 6.3.5
### Patch Changes
- [#2076](https://github.com/marko-js/marko/pull/2076) [`69b3ff5`](https://github.com/marko-js/marko/commit/69b3ff57c829418946e05c13b644a5560f589086) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Upgrade all package deps to latest
## 6.3.4
### Patch Changes
- [#2060](https://github.com/marko-js/marko/pull/2060) [`648a94928`](https://github.com/marko-js/marko/commit/648a94928f662b04634a61395d5d48a956a8ff36) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Expose meta data about which child Marko templates were analyzed for a given compilation.
## 6.3.3
### Patch Changes
- [#2054](https://github.com/marko-js/marko/pull/2054) [`1c5eccadf`](https://github.com/marko-js/marko/commit/1c5eccadf8d968552dbe8756905009107d783718) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Fix regression with @marko/babel-utils not exposing new parse helpers.
## 6.3.2
### Patch Changes
- [#2051](https://github.com/marko-js/marko/pull/2051) [`5354d4411`](https://github.com/marko-js/marko/commit/5354d44112c56fcbbd7f44dd3bf91be1e5a7747c) Thanks [@LuLaValva](https://github.com/LuLaValva)! - add ts to ast
## 6.3.1
### Patch Changes
- [#2008](https://github.com/marko-js/marko/pull/2008) [`1235cf700`](https://github.com/marko-js/marko/commit/1235cf7005447bdad7a84bacf20d40c7c457c03a) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Fix regression with static template literal expressions.
## 6.3.0
### Minor Changes
- [#2006](https://github.com/marko-js/marko/pull/2006) [`b2e70bc45`](https://github.com/marko-js/marko/commit/b2e70bc45006a8cccfa61ac99bbca40a71d05fd1) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Add compute node helper to replace babels `evaluate` helper. This helper is less aggressive and doesn't suffer from the false positives that popped up with babels version.
## 6.2.1
### Patch Changes

View File

@ -74,11 +74,11 @@ export interface TaglibLookup {
getTag(tagName: string): undefined | TagDefinition;
getAttribute(
tagName: string,
attrName: string
attrName: string,
): undefined | AttributeDefinition;
forEachAttribute(
tagName: string,
callback: (attr: AttributeDefinition, tag: TagDefinition) => void
callback: (attr: AttributeDefinition, tag: TagDefinition) => void,
): void;
}
@ -143,7 +143,7 @@ export function defineTag<T extends Tag>(tag: T): T;
export type FunctionPlugin<T = any> = (
path: t.NodePath<T>,
types: typeof t
types: typeof t,
) => void;
type EnterExitPlugin<T = any> = {
enter?(path: t.NodePath<T>, types: typeof t): void;
@ -161,7 +161,7 @@ export type Plugin<T = any> =
export function assertAllowedAttributes(
path: t.NodePath<t.MarkoTag>,
allowed: string[]
allowed: string[],
): void;
export function assertNoArgs(path: t.NodePath<t.MarkoTag>): void;
export function assertNoVar(path: t.NodePath<t.MarkoTag>): void;
@ -180,31 +180,31 @@ export function registerMacro(path: t.NodePath<any>, name: string): void;
export function hasMacro(path: t.NodePath<any>, name: string): boolean;
export function getMacroIdentifierForName(
path: t.NodePath<any>,
name: string
name: string,
): t.Identifier;
export function getMacroIdentifier(path: t.NodePath<t.MarkoTag>): t.Identifier;
export function getTagDef(
path: t.NodePath<t.MarkoTag>
path: t.NodePath<t.MarkoTag>,
): TagDefinition | undefined;
export function getFullyResolvedTagName(path: t.NodePath<t.MarkoTag>): string;
export function findParentTag(
path: t.NodePath<t.MarkoTag>
path: t.NodePath<t.MarkoTag>,
): t.NodePath<t.MarkoTag> | undefined;
export function findAttributeTags(
path: t.NodePath<t.MarkoTag>
path: t.NodePath<t.MarkoTag>,
): Array<t.NodePath<t.MarkoTag>>;
export function getArgOrSequence(
path: t.NodePath<t.MarkoTag | t.MarkoAttribute>
path: t.NodePath<t.MarkoTag | t.MarkoAttribute>,
): t.Expression;
export function loadFileForTag(
path: t.NodePath<t.MarkoTag>
path: t.NodePath<t.MarkoTag>,
): t.BabelFile | undefined;
export function loadFileForImport(
file: t.BabelFile,
template: string
template: string,
): t.BabelFile | undefined;
export function normalizeTemplateString(
@ -219,13 +219,13 @@ export function getLoc(file: t.BabelFile, pos: number): Loc;
export function getLocRange(
file: t.BabelFile,
start: number,
end: number
end: number,
): LocRange;
export function withLoc<T extends t.Node>(
file: t.BabelFile,
node: T,
start: number,
end: number
end: number,
): T;
export function parseStatements(file: t.BabelFile, str: string): t.Statement[];
@ -234,7 +234,7 @@ export function parseStatements(
str: string,
sourceStart: number,
sourceEnd: number,
sourceOffset?: number
sourceOffset?: number,
): t.Statement[];
export function parseExpression(file: t.BabelFile, str: string): t.Expression;
@ -243,76 +243,76 @@ export function parseExpression(
str: string,
sourceStart: number,
sourceEnd: number,
sourceOffset?: number
sourceOffset?: number,
): t.Expression;
export function parseParams(
file: t.BabelFile,
str: string
str: string,
): t.Function["params"];
export function parseParams(
file: t.BabelFile,
str: string,
sourceStart: number,
sourceEnd: number
sourceEnd: number,
): t.Function["params"];
export function parseArgs(
file: t.BabelFile,
str: string
str: string,
): t.CallExpression["arguments"];
export function parseArgs(
file: t.BabelFile,
str: string,
sourceStart: number,
sourceEnd: number
sourceEnd: number,
): t.CallExpression["arguments"];
export function parseVar(
file: t.BabelFile,
str: string
str: string,
): t.VariableDeclarator["id"];
export function parseVar(
file: t.BabelFile,
str: string,
sourceStart: number,
sourceEnd: number
sourceEnd: number,
): t.VariableDeclarator["id"];
export function parseTemplateLiteral(
file: t.BabelFile,
str: string
str: string,
): t.TemplateLiteral;
export function parseTemplateLiteral(
file: t.BabelFile,
str: string,
sourceStart: number,
sourceEnd: number
sourceEnd: number,
): t.TemplateLiteral;
export function resolveRelativePath(file: t.BabelFile, request: string): string;
export function importDefault(
file: t.BabelFile,
request: string,
nameHint?: string
nameHint?: string,
): t.Identifier;
export function importNamed(
file: t.BabelFile,
request: string,
name: string,
nameHint?: string
nameHint?: string,
): t.Identifier;
export function getTaglibLookup(file: t.BabelFile): TaglibLookup;
export function getTagDefForTagName(
file: t.BabelFile,
tagName: string
tagName: string,
): TagDefinition | undefined;
export function getTemplateId(optimize: boolean, request: string): string;
export function resolveTagImport(
path: t.NodePath<any>,
request: string
request: string,
): string | undefined;
export enum DiagnosticType {
@ -345,19 +345,19 @@ export interface DiagnosticOptions {
export function diagnosticError(
path: t.NodePath<any>,
options: DiagnosticOptions
options: DiagnosticOptions,
): void;
export function diagnosticWarn(
path: t.NodePath<any>,
options: DiagnosticOptions
options: DiagnosticOptions,
): void;
export function diagnosticDeprecate(
path: t.NodePath<any>,
options: DiagnosticOptions
options: DiagnosticOptions,
): void;
export function diagnosticSuggest(
path: t.NodePath<any>,
options: DiagnosticOptions
options: DiagnosticOptions,
): void;
interface ConfirmFix {
@ -375,3 +375,15 @@ interface SelectFix {
}[];
initialValue?: string;
}
type Computed =
| undefined
| number
| string
| boolean
| RegExp
| bigint
| null
| { [x: string]: Computed }
| Computed[];
export function computeNode(node: t.Node): undefined | { value: Computed };

View File

@ -1,6 +1,6 @@
{
"name": "@marko/babel-utils",
"version": "6.2.1",
"version": "6.3.5",
"description": "Utilities for use with Marko babel plugins.",
"keywords": [
"htmljs",
@ -28,12 +28,12 @@
"build": "babel ./src --out-dir ./dist --delete-dir-on-start --copy-files --config-file ../../babel.config.js --env-name=production"
},
"dependencies": {
"@babel/runtime": "^7.16.0",
"@babel/runtime": "^7.23.8",
"jsesc": "^3.0.2",
"relative-import-path": "^1.0.0"
},
"devDependencies": {
"@marko/compiler": "^5.30.0"
"@marko/compiler": "^5.34.4"
},
"publishConfig": {
"access": "public"

View File

@ -5,7 +5,7 @@ export function assertAllowedAttributes(path, allowed) {
throw path
.get(`attributes.${i}`)
.buildCodeFrameError(
`Invalid "${node.name.value}" tag attribute: "${attr.name}".`
`Invalid "${node.name.value}" tag attribute: "${attr.name}".`,
);
}
});
@ -22,7 +22,7 @@ export function assertNoParams(path) {
const end = params[params.length - 1].loc.end;
throw path.hub.buildError(
{ loc: { start, end } },
"Tag does not support parameters."
"Tag does not support parameters.",
);
}
}
@ -44,7 +44,7 @@ export function assertNoArgs(path) {
const end = args[args.length - 1].node.loc.end;
throw hub.buildError(
{ loc: { start, end } },
"Tag does not support arguments."
"Tag does not support arguments.",
);
}
}

View File

@ -0,0 +1,194 @@
/**
* @param {import("@babel/types").Node} node
*/
export function computeNode(node) {
switch (node.type) {
case "StringLiteral":
case "NumericLiteral":
case "BooleanLiteral":
return { value: node.value };
case "RegExpLiteral":
return { value: new RegExp(node.pattern, node.flags) };
case "NullLiteral":
return { value: null };
case "Identifier":
switch (node.name) {
case "undefined":
return { value: undefined };
case "NaN":
return { value: NaN };
case "Infinity":
return { value: Infinity };
default:
return;
}
case "BigIntLiteral":
return { value: BigInt(node.value) };
case "BinaryExpression": {
const left = computeNode(node.left);
if (!left) return;
const right = computeNode(node.right);
if (!right) return;
switch (node.operator) {
case "+":
return { value: left.value + right.value };
case "-":
return { value: left.value - right.value };
case "*":
return { value: left.value * right.value };
case "/":
return { value: left.value / right.value };
case "%":
return { value: left.value % right.value };
case "**":
return { value: left.value ** right.value };
case "|":
return { value: left.value | right.value };
case "&":
return { value: left.value & right.value };
case "^":
return { value: left.value ^ right.value };
case "<<":
return { value: left.value << right.value };
case ">>":
return { value: left.value >> right.value };
case ">>>":
return { value: left.value >>> right.value };
case "==":
return { value: left.value == right.value };
case "!=":
return { value: left.value != right.value };
case "===":
return { value: left.value === right.value };
case "!==":
return { value: left.value !== right.value };
case "<":
return { value: left.value < right.value };
case "<=":
return { value: left.value <= right.value };
case ">":
return { value: left.value > right.value };
case ">=":
return { value: left.value >= right.value };
default:
return;
}
}
case "UnaryExpression": {
const arg = computeNode(node.argument);
if (!arg) return;
switch (node.operator) {
case "+":
return { value: +arg.value };
case "-":
return { value: -arg.value };
case "~":
return { value: ~arg.value };
case "!":
return { value: !arg.value };
case "typeof":
return { value: typeof arg.value };
case "void":
return { value: void arg.value };
default:
return;
}
}
case "LogicalExpression": {
const left = computeNode(node.left);
if (!left) return;
const right = computeNode(node.right);
if (!right) return;
switch (node.operator) {
case "&&":
return { value: left.value && right.value };
case "||":
return { value: left.value || right.value };
case "??":
return { value: left.value ?? right.value };
default:
return;
}
}
case "ConditionalExpression": {
const test = computeNode(node.test);
if (!test) return;
const consequent = computeNode(node.consequent);
if (!consequent) return;
const alternate = computeNode(node.alternate);
if (!alternate) return;
return { value: test.value ? consequent.value : alternate.value };
}
case "TemplateLiteral": {
let value = node.quasis[0].value.cooked;
for (let i = 0; i < node.expressions.length; i++) {
const expr = computeNode(node.expressions[i]);
if (!expr) return;
value += expr.value + node.quasis[i + 1].value.cooked;
}
return { value };
}
case "ObjectExpression": {
const value = {};
for (const prop of node.properties) {
if (prop.decorators) return;
switch (prop.type) {
case "ObjectProperty": {
let key;
if (prop.computed) {
const keyNode = computeNode(prop.key);
if (!keyNode) return;
key = keyNode.value + "";
} else {
switch (prop.key.type) {
case "Identifier":
key = prop.key.name;
break;
case "StringLiteral":
key = prop.key.value;
break;
default:
return;
}
}
const propValue = computeNode(prop.value);
if (!propValue) return;
value[key] = propValue.value;
break;
}
case "SpreadElement": {
const arg = computeNode(prop.argument);
if (!arg) return;
Object.assign(value, arg.value);
break;
}
}
}
return { value };
}
case "ArrayExpression": {
const value = [];
for (const elem of node.elements) {
if (elem) {
if (elem.type === "SpreadElement") {
const arg = computeNode(elem.argument);
if (typeof arg?.value?.[Symbol.iterator] !== "function") return;
for (const item of arg.value) {
value.push(item);
}
} else {
const elemValue = computeNode(elem);
if (!elemValue) return;
value.push(elemValue.value);
}
} else {
value.length++;
}
}
return { value };
}
}
}

View File

@ -30,7 +30,7 @@ function add(type, path, options) {
if (rawFix) {
if (file.___compileStage !== "migrate") {
throw new Error(
"Diagnostic fixes can only be registered during the migrate stage."
"Diagnostic fixes can only be registered during the migrate stage.",
);
}

View File

@ -13,7 +13,7 @@ export function resolveRelativePath(file, request) {
if (file.markoOpts.optimize) {
request = request.replace(
/(^|\/node-modules\/)marko\/src\//,
"$1marko/dist/"
"$1marko/dist/",
);
}
@ -30,8 +30,8 @@ export function importDefault(file, request, nameHint) {
request,
(importDeclaration = file.path.pushContainer(
"body",
t.importDeclaration([], t.stringLiteral(request))
)[0])
t.importDeclaration([], t.stringLiteral(request)),
)[0]),
);
}
@ -41,14 +41,14 @@ export function importDefault(file, request, nameHint) {
const specifiers = importDeclaration.get("specifiers");
const specifier = specifiers.find((specifier) =>
specifier.isImportDefaultSpecifier()
specifier.isImportDefaultSpecifier(),
);
if (!specifier) {
const identifier = file.scope.generateUidIdentifier(nameHint);
importDeclaration.pushContainer(
"specifiers",
t.importDefaultSpecifier(identifier)
t.importDefaultSpecifier(identifier),
);
return identifier;
}
@ -66,22 +66,22 @@ export function importNamed(file, request, name, nameHint = name) {
request,
(importDeclaration = file.path.pushContainer(
"body",
t.importDeclaration([], t.stringLiteral(request))
)[0])
t.importDeclaration([], t.stringLiteral(request)),
)[0]),
);
}
const specifiers = importDeclaration.get("specifiers");
const specifier = specifiers.find(
(specifier) =>
specifier.isImportSpecifier() && specifier.node.imported.name === name
specifier.isImportSpecifier() && specifier.node.imported.name === name,
);
if (!specifier) {
const identifier = file.scope.generateUidIdentifier(nameHint);
importDeclaration.pushContainer(
"specifiers",
t.importSpecifier(identifier, t.identifier(name))
t.importSpecifier(identifier, t.identifier(name)),
);
return identifier;
}

View File

@ -27,6 +27,7 @@ export {
assertNoVar,
assertNoAttributeTags,
} from "./assert";
export { computeNode } from "./compute";
export { normalizeTemplateString } from "./template-string";
export { getLoc, getLocRange, withLoc } from "./loc";
@ -38,6 +39,8 @@ export {
parseArgs,
parseVar,
parseTemplateLiteral,
parseTypeArgs,
parseTypeParams,
} from "./parse";
export { resolveRelativePath, importDefault, importNamed } from "./imports";

View File

@ -1,6 +1,6 @@
import * as babelParser from "@babel/parser";
import { getLocRange } from "./loc";
import { types as t } from "@marko/compiler";
import { getLocRange } from "./loc";
const CODE_AS_WHITE_SPACE_KEY = Symbol();
@ -9,7 +9,7 @@ export function parseStatements(
str,
sourceStart,
sourceEnd,
sourceOffset
sourceOffset,
) {
return tryParse(file, false, str, sourceStart, sourceEnd, sourceOffset);
}
@ -19,7 +19,7 @@ export function parseExpression(
str,
sourceStart,
sourceEnd,
sourceOffset
sourceOffset,
) {
return tryParse(file, true, str, sourceStart, sourceEnd, sourceOffset);
}
@ -30,7 +30,7 @@ export function parseParams(file, str, sourceStart, sourceEnd) {
`(${str})=>{}`,
sourceStart,
sourceEnd,
1
1,
);
if (parsed.type === "ArrowFunctionExpression") {
@ -56,7 +56,7 @@ export function parseVar(file, str, sourceStart, sourceEnd) {
`(${str})=>{}`,
sourceStart,
sourceEnd,
1
1,
);
if (parsed.type === "ArrowFunctionExpression" && parsed.params.length === 1) {
@ -72,7 +72,7 @@ export function parseTemplateLiteral(file, str, sourceStart, sourceEnd) {
"`" + str + "`",
sourceStart,
sourceEnd,
1
1,
);
if (parsed.type === "TemplateLiteral") {
@ -82,13 +82,40 @@ export function parseTemplateLiteral(file, str, sourceStart, sourceEnd) {
return ensureParseError(file, parsed, sourceStart, sourceEnd);
}
export function parseTypeArgs(file, str, sourceStart, sourceEnd) {
const parsed = parseExpression(file, `_<${str}>`, sourceStart, sourceEnd, 2);
if (parsed.type === "TSInstantiationExpression") {
// typeArguments is Flow only (not TS), we need to use typeParameters
return parsed.typeParameters;
}
return [ensureParseError(file, parsed, sourceStart, sourceEnd)];
}
export function parseTypeParams(file, str, sourceStart, sourceEnd) {
const parsed = parseExpression(
file,
`<${str}>()=>{}`,
sourceStart,
sourceEnd,
1,
);
if (parsed.type === "ArrowFunctionExpression") {
return parsed.typeParameters;
}
return [ensureParseError(file, parsed, sourceStart, sourceEnd)];
}
function tryParse(
file,
isExpression,
str,
sourceStart,
sourceEnd,
sourceOffset
sourceOffset,
) {
const { parserOpts } = file.opts;
let code = str;
@ -98,12 +125,12 @@ function tryParse(
file.metadata.marko[CODE_AS_WHITE_SPACE_KEY] ||
(file.metadata.marko[CODE_AS_WHITE_SPACE_KEY] = file.code.replace(
/[^\s]/g,
" "
" ",
));
code =
whitespace.slice(
0,
sourceOffset ? sourceStart - sourceOffset : sourceStart
sourceOffset ? sourceStart - sourceOffset : sourceStart,
) + str;
try {
@ -116,7 +143,7 @@ function tryParse(
sourceStart,
sourceEnd,
err.message,
err.loc
err.loc,
);
if (isExpression) {
@ -140,7 +167,7 @@ function ensureParseError(file, node, sourceStart, sourceEnd) {
file,
sourceStart,
sourceEnd,
`Unexpected node of type ${node.type} returned while parsing.`
`Unexpected node of type ${node.type} returned while parsing.`,
);
}

View File

@ -1,10 +1,10 @@
import { basename, dirname, relative, resolve } from "path";
import resolveFrom from "resolve-from";
import { createHash } from "crypto";
import { basename, dirname, relative, resolve } from "path";
import { types as t } from "@marko/compiler";
import { getRootDir } from "lasso-package-root";
import { getTagDefForTagName } from "./taglib";
import resolveFrom from "resolve-from";
import { resolveRelativePath } from "./imports";
import { getTagDefForTagName } from "./taglib";
const MACRO_IDS_KEY = Symbol();
const MACRO_NAMES_KEY = "__marko_macro_names__"; // must be a string literal since it is used across compiler stages.
@ -64,7 +64,7 @@ export function registerMacro(path, name) {
if (macroNames) {
if (macroNames[name]) {
throw path.buildCodeFrameError(
`A macro with the name "${name}" already exists.`
`A macro with the name "${name}" already exists.`,
);
}
macroNames[name] = true;
@ -88,7 +88,7 @@ export function getMacroIdentifierForName(path, name) {
if (file.___compileStage !== "translate") {
throw new Error(
"getMacroIdentifierForName can only be called during the translate phase of the compiler."
"getMacroIdentifierForName can only be called during the translate phase of the compiler.",
);
}
@ -107,7 +107,7 @@ export function getMacroIdentifierForName(path, name) {
if (!id) {
throw new Error(
"<macro> was added programmatically, but was not registered via the 'registerMacro' api in @marko/babel-utils."
"<macro> was added programmatically, but was not registered via the 'registerMacro' api in @marko/babel-utils.",
);
}
@ -119,13 +119,13 @@ export function getMacroIdentifier(path) {
if (file.___compileStage !== "translate") {
throw new Error(
"getMacroIdentifier can only be called during the translate phase of the compiler."
"getMacroIdentifier can only be called during the translate phase of the compiler.",
);
}
if (!isMacroTag(path)) {
throw path.buildCodeFrameError(
"getMacroIdentifier called on non macro referencing tag."
"getMacroIdentifier called on non macro referencing tag.",
);
}
@ -145,7 +145,9 @@ export function getTagDef(path) {
node.tagDef =
getTagDefForTagName(
file,
isAttributeTag(path) ? getFullyResolvedTagName(path) : node.name.value
isAttributeTag(path)
? getFullyResolvedTagName(path)
: node.name.value,
) || null;
}
}
@ -236,10 +238,18 @@ export function loadFileForTag(tag) {
const filename = def && def.template;
if (filename) {
const markoMeta = file.metadata.marko;
const { analyzedTags } = markoMeta;
if (analyzedTags) {
analyzedTags.push(filename);
} else {
markoMeta.analyzedTags = [filename];
}
return file.___getMarkoFile(
fs.readFileSync(filename).toString("utf-8"),
createNewFileOpts(file.opts, filename),
file.markoOpts
file.markoOpts,
);
}
}
@ -253,10 +263,18 @@ export function loadFileForImport(file, request) {
relativeRequest[0] === "."
? resolve(file.opts.filename, "..", relativeRequest)
: resolveFrom(dirname(file.opts.filename), relativeRequest);
const markoMeta = file.metadata.marko;
const { analyzedTags } = markoMeta;
if (analyzedTags) {
analyzedTags.push(filename);
} else {
markoMeta.analyzedTags = [filename];
}
return file.___getMarkoFile(
fs.readFileSync(filename).toString("utf-8"),
createNewFileOpts(file.opts, filename),
file.markoOpts
file.markoOpts,
);
}
}
@ -283,7 +301,7 @@ export function resolveTagImport(path, request) {
if (!relativePath) {
throw path.buildCodeFrameError(
`Unable to find entry point for custom tag <${tagName}>.`
`Unable to find entry point for custom tag <${tagName}>.`,
);
}

View File

@ -1,5 +1,5 @@
import jsesc from "jsesc";
import { types as t } from "@marko/compiler";
import jsesc from "jsesc";
export function normalizeTemplateString(quasis, ...expressions) {
quasis = quasis.map((q) => (t.isTemplateElement(q) ? q.value.cooked : q));
@ -13,7 +13,7 @@ export function normalizeTemplateString(quasis, ...expressions) {
quasis.splice(
i + 1,
0,
...v.quasis.slice(1, -1).map((q) => q.value.cooked)
...v.quasis.slice(1, -1).map((q) => q.value.cooked),
);
expressions.splice(i, 1, ...v.expressions);
i += v.expressions.length;

View File

@ -1,5 +1,114 @@
# Change Log
## 5.34.4
### Patch Changes
- [#2076](https://github.com/marko-js/marko/pull/2076) [`69b3ff5`](https://github.com/marko-js/marko/commit/69b3ff57c829418946e05c13b644a5560f589086) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Upgrade all package deps to latest
- Updated dependencies [[`69b3ff5`](https://github.com/marko-js/marko/commit/69b3ff57c829418946e05c13b644a5560f589086)]:
- @marko/babel-utils@6.3.5
## 5.34.3
### Patch Changes
- [#2074](https://github.com/marko-js/marko/pull/2074) [`bf23c566fac02f4e2991be357a95483663493b3f`](https://github.com/marko-js/marko/commit/bf23c566fac02f4e2991be357a95483663493b3f) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Upgrade package lock and built types.
## 5.34.2
### Patch Changes
- [#2069](https://github.com/marko-js/marko/pull/2069) [`977d69078`](https://github.com/marko-js/marko/commit/977d690784f1d97acb3494bb822fa852c1380685) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Fix issue with printing variable declarations with multiple variables.
## 5.34.1
### Patch Changes
- [#2064](https://github.com/marko-js/marko/pull/2064) [`5e294103f`](https://github.com/marko-js/marko/commit/5e294103f78642b8a44887a1569ffd0eabcf6821) Thanks [@LuLaValva](https://github.com/LuLaValva)! - fix sourcemaps
## 5.34.0
### Minor Changes
- [#2062](https://github.com/marko-js/marko/pull/2062) [`436ace040`](https://github.com/marko-js/marko/commit/436ace040b73d11908911d60c10845b6e99e8eca) Thanks [@LuLaValva](https://github.com/LuLaValva)! - Add "exports" to marko.json
## 5.33.8
### Patch Changes
- [#2060](https://github.com/marko-js/marko/pull/2060) [`648a94928`](https://github.com/marko-js/marko/commit/648a94928f662b04634a61395d5d48a956a8ff36) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Expose meta data about which child Marko templates were analyzed for a given compilation.
- [#2059](https://github.com/marko-js/marko/pull/2059) [`aed88284b`](https://github.com/marko-js/marko/commit/aed88284b8b3c68965f70b6bdf9412c7100c5df5) Thanks [@LuLaValva](https://github.com/LuLaValva)! - fix AST types
- Updated dependencies [[`648a94928`](https://github.com/marko-js/marko/commit/648a94928f662b04634a61395d5d48a956a8ff36)]:
- @marko/babel-utils@6.3.4
## 5.33.7
### Patch Changes
- [#2056](https://github.com/marko-js/marko/pull/2056) [`84f443d60`](https://github.com/marko-js/marko/commit/84f443d60539cc1b3382c6b16da4061070f97aca) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Fix issue when the Marko hot-reload runtime is loaded in native esm
## 5.33.6
### Patch Changes
- [#2054](https://github.com/marko-js/marko/pull/2054) [`1c5eccadf`](https://github.com/marko-js/marko/commit/1c5eccadf8d968552dbe8756905009107d783718) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Fix regression with @marko/babel-utils not exposing new parse helpers.
- Updated dependencies [[`1c5eccadf`](https://github.com/marko-js/marko/commit/1c5eccadf8d968552dbe8756905009107d783718)]:
- @marko/babel-utils@6.3.3
## 5.33.5
### Patch Changes
- [#2051](https://github.com/marko-js/marko/pull/2051) [`5354d4411`](https://github.com/marko-js/marko/commit/5354d44112c56fcbbd7f44dd3bf91be1e5a7747c) Thanks [@LuLaValva](https://github.com/LuLaValva)! - add ts to ast
- Updated dependencies [[`5354d4411`](https://github.com/marko-js/marko/commit/5354d44112c56fcbbd7f44dd3bf91be1e5a7747c)]:
- @marko/babel-utils@6.3.2
## 5.33.4
### Patch Changes
- [#2049](https://github.com/marko-js/marko/pull/2049) [`1554b1e1e`](https://github.com/marko-js/marko/commit/1554b1e1e53a75980af0b238cc27bed5ddfa215a) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Allow `template.marko` to act as `index.marko` for backword compat with v4/v3.
## 5.33.3
### Patch Changes
- [#2042](https://github.com/marko-js/marko/pull/2042) [`447104632`](https://github.com/marko-js/marko/commit/44710463258999ad037febef10264e32f3291157) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - When compiling async, prefer using the async babel api for loading babel config files.
## 5.33.2
### Patch Changes
- [#2038](https://github.com/marko-js/marko/pull/2038) [`71a227a5f`](https://github.com/marko-js/marko/commit/71a227a5ff8b16c0bb983e082f28280518f712ce) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Fix issue where using the longhand nested attribute tag syntax in a marko.json with a `target-property` defined was not registering the alias as a known attribute, leading to compile errors.
## 5.33.1
### Patch Changes
- [#2020](https://github.com/marko-js/marko/pull/2020) [`6a4e947b5`](https://github.com/marko-js/marko/commit/6a4e947b5ac9944e61d7871d314a6325a0522d1d) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Ensure .marko files are resolved for legacy renderer taglib configs.
## 5.33.0
### Minor Changes
- [#2012](https://github.com/marko-js/marko/pull/2012) [`6ba268c84`](https://github.com/marko-js/marko/commit/6ba268c841631b3ed36964c8f532e543885ad4f5) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Support registering a taglib in the compiler by just passing in a module id.
## 5.32.0
### Minor Changes
- [#2006](https://github.com/marko-js/marko/pull/2006) [`b2e70bc45`](https://github.com/marko-js/marko/commit/b2e70bc45006a8cccfa61ac99bbca40a71d05fd1) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Add compute node helper to replace babels `evaluate` helper. This helper is less aggressive and doesn't suffer from the false positives that popped up with babels version.
### Patch Changes
- Updated dependencies [[`b2e70bc45`](https://github.com/marko-js/marko/commit/b2e70bc45006a8cccfa61ac99bbca40a71d05fd1)]:
- @marko/babel-utils@6.3.0
## 5.31.2
### Patch Changes

View File

@ -1,3 +1,4 @@
/* eslint-disable import/export */
import { Scope } from "./dist/traverse";
export * from "./dist/types";
export * from "./dist/traverse";

View File

@ -18,10 +18,11 @@ declare const Config: {
resolveVirtualDependency?:
| ((
filename: string,
dep: { virtualPath: string; code: string; map?: any }
dep: { virtualPath: string; code: string; map?: any },
) => string)
| null;
hydrateIncludeImports?: RegExp | ((request: string) => boolean);
hydrateInit?: boolean;
optimize?: boolean;
cache?: Map<unknown, unknown>;
hot?: boolean;

View File

@ -1,28 +1,32 @@
import { SourceMap } from "magic-string";
import { Diagnostic, TaglibLookup } from "@marko/babel-utils";
import { SourceMap } from "magic-string";
import * as types from "./babel-types";
export { types };
type _Config = typeof import("./config");
export interface Config extends _Config {}
interface Dep {
type: string;
path: string;
[x: string]: unknown;
}
type Dep = {
interface VirtualDep {
type: string;
code: string;
path: string;
virtualPath: string;
startPos?: number;
endPos?: number;
require?: boolean;
virtualPath?: string;
[x: string]: unknown;
};
}
export interface MarkoMeta {
id: string;
component?: string;
watchFiles: string[];
tags?: string[];
deps: Array<string | Dep>;
deps: Array<string | Dep | VirtualDep>;
analyzedTags?: [string, ...string[]];
diagnostics: Diagnostic[];
}
@ -38,38 +42,39 @@ export function configure(config: Config): void;
export function compile(
src: string,
filename: string,
config?: Config
config?: Config,
): Promise<CompileResult>;
export function compileSync(
src: string,
filename: string,
config?: Config
config?: Config,
): CompileResult;
export function compileFile(
filename: string,
config?: Config
config?: Config,
): Promise<CompileResult>;
export function compileFileSync(
filename: string,
config?: Config
config?: Config,
): CompileResult;
export function getRuntimeEntryFiles(
output: string,
translator?: string | undefined
translator?: string | undefined,
): string[];
export namespace taglib {
export function excludeDir(dirname: string): void;
export function excludePackage(packageName: string): void;
export function register(id: string): void;
export function register(id: string, props: { [x: string]: unknown }): void;
export function buildLookup(
dirname: string,
translator?: unknown,
onError?: (err: Error) => void
onError?: (err: Error) => void,
): TaglibLookup;
export function clearCaches(): void;
}

View File

@ -1,6 +1,6 @@
{
"name": "@marko/compiler",
"version": "5.31.2",
"version": "5.34.4",
"description": "Marko template to JS compiler.",
"keywords": [
"babel",
@ -35,20 +35,21 @@
"build:types": "node scripts/types-babel-types.mjs > ./dist/types.d.ts && node scripts/types-babel-traverse.js > ./dist/traverse.d.ts"
},
"dependencies": {
"@babel/code-frame": "^7.16.0",
"@babel/core": "^7.16.0",
"@babel/generator": "^7.16.0",
"@babel/parser": "^7.16.0",
"@babel/plugin-syntax-typescript": "^7.16.0",
"@babel/plugin-transform-modules-commonjs": "^7.16.0",
"@babel/plugin-transform-typescript": "^7.16.0",
"@babel/runtime": "^7.16.0",
"@babel/traverse": "^7.16.0",
"@babel/types": "^7.16.0",
"@marko/babel-utils": "^6.2.1",
"@babel/code-frame": "^7.23.5",
"@babel/core": "^7.23.7",
"@babel/generator": "^7.23.6",
"@babel/parser": "^7.23.6",
"@babel/plugin-syntax-typescript": "^7.23.3",
"@babel/plugin-transform-modules-commonjs": "^7.23.3",
"@babel/plugin-transform-typescript": "^7.23.6",
"@babel/runtime": "^7.23.8",
"@babel/traverse": "^7.23.7",
"@babel/types": "^7.23.6",
"@luxass/strip-json-comments": "^1.1.1",
"@marko/babel-utils": "^6.3.5",
"complain": "^1.6.0",
"he": "^1.2.0",
"htmljs-parser": "^5.4.3",
"htmljs-parser": "^5.5.2",
"jsesc": "^3.0.2",
"kleur": "^4.1.5",
"lasso-package-root": "^1.0.1",
@ -56,12 +57,10 @@
"raptor-util": "^3.2.0",
"resolve-from": "^5.0.0",
"self-closing-tags": "^1.0.1",
"source-map-support": "^0.5.21",
"strip-ansi": "^6.0.0",
"strip-json-comments": "^3.1.1"
"source-map-support": "^0.5.21"
},
"devDependencies": {
"@marko/translator-default": "^5.29.1"
"@marko/translator-default": "^5.31.11"
},
"publishConfig": {
"access": "public"

View File

@ -2,5 +2,5 @@ import { Config } from ".";
type Extensions = Partial<typeof require.extensions>;
export default function register(
config: Config & { extensions?: Extensions }
config: Config & { extensions?: Extensions },
): Extensions;

View File

@ -33,14 +33,14 @@ const { MARKO_TYPES } = require("../dist/babel-types/types/definitions");
const HUB_INTERFACE = "export interface HubInterface {";
const HUB_CLASS =
"export class Hub implements HubInterface {\n constructor();";
const IMPORT = "import * as t from '@babel/types'";
const IMPORT = 'import * as t from "@babel/types"';
const EXPORT_NODE = "export import Node = t.Node;";
const NODE_PATH_GET =
"get(key: string, context?: boolean | TraversalContext): NodePath | NodePath[];";
const IS =
"//#region ------------------------- isXXX -------------------------";
"// #region ------------------------- isXXX -------------------------";
const ASSERT =
"//#region ------------------------- assertXXX -------------------------";
"// #region ------------------------- assertXXX -------------------------";
const BREAK = "\n ";
fs.readFile(
@ -53,11 +53,11 @@ fs.readFile(
(str) => {
if (data.indexOf(str) === -1) {
console.error(
`Unable to find \`${str}\` in @types/babel__traverse/index.d.ts`
`Unable to find \`${str}\` in @types/babel__traverse/index.d.ts`,
);
process.exit(1);
}
}
},
);
var result = data
@ -76,12 +76,12 @@ fs.readFile(
}
${HUB_INTERFACE}
file: BabelFile;`
file: BabelFile;`,
)
.replace(
HUB_CLASS,
`${HUB_CLASS}
file: BabelFile;`
file: BabelFile;`,
)
.replace(IMPORT, `import * as t from './types'`)
.replace(EXPORT_NODE, "type Node = t.Node")
@ -91,18 +91,18 @@ ${HUB_INTERFACE}
IS +
BREAK +
MARKO_TYPES.map(
(t) => `is${t}(props?: object | null): this is NodePath<t.${t}>;`
).join(BREAK)
(t) => `is${t}(opts?: object | null): this is NodePath<t.${t}>;`,
).join(BREAK),
)
.replace(
ASSERT,
ASSERT +
BREAK +
MARKO_TYPES.map(
(t) => `assert${t}(props?: object | null): void;`
).join(BREAK)
(t) => `assert${t}(opts?: object | null): void;`,
).join(BREAK),
);
process.stdout.write(result);
}
},
);

View File

@ -1,25 +1,25 @@
import path from "path";
import { createHash } from "crypto";
import * as t from "../babel-types";
import { diagnosticError, getTemplateId } from "@marko/babel-utils";
import path from "path";
import { visitors } from "@babel/traverse";
import { diagnosticError, getTemplateId } from "@marko/babel-utils";
import * as t from "../babel-types";
import { buildLookup } from "../taglib";
import taglibConfig from "../taglib/config";
import { buildCodeFrameError } from "../util/build-code-frame";
import throwAggregateError from "../util/merge-errors";
import shouldOptimize from "../util/should-optimize";
import tryLoadTranslator from "../util/try-load-translator";
import { MarkoFile } from "./file";
import { parseMarko } from "./parser";
import { visitor as migrate } from "./plugins/migrate";
import { visitor as transform } from "./plugins/transform";
import { MarkoFile } from "./file";
import taglibConfig from "../taglib/config";
import tryLoadTranslator from "../util/try-load-translator";
import shouldOptimize from "../util/should-optimize";
import { buildCodeFrameError } from "../util/build-code-frame";
import throwAggregateError from "../util/merge-errors";
const SOURCE_FILES = new WeakMap();
export default (api, markoOpts) => {
api.assertVersion(7);
const translator = (markoOpts.translator = tryLoadTranslator(
markoOpts.translator
markoOpts.translator,
));
markoOpts.output = markoOpts.output || "html";
@ -30,7 +30,7 @@ export default (api, markoOpts) => {
if (!translator || !translator.translate) {
throw new Error(
"@marko/compiler: translator must provide a translate visitor object"
"@marko/compiler: translator must provide a translate visitor object",
);
}
@ -39,7 +39,7 @@ export default (api, markoOpts) => {
typeof markoOpts.resolveVirtualDependency !== "function"
) {
throw new Error(
`@marko/compiler: the "resolveVirtualDependency" option must be supplied when output is "hydrate".`
`@marko/compiler: the "resolveVirtualDependency" option must be supplied when output is "hydrate".`,
);
}
@ -100,7 +100,7 @@ export default (api, markoOpts) => {
addPlugin(
metadata.marko,
rootTranslators,
taglibLookup.taglibsById[id].translator
taglibLookup.taglibsById[id].translator,
);
}
}
@ -127,7 +127,7 @@ export default (api, markoOpts) => {
MarkoClass(path) {
// We replace the MarkoClass with a regular class declaration so babel can strip it's types.
path.replaceWith(
t.classDeclaration(t.identifier(""), null, path.node.body)
t.classDeclaration(t.identifier(""), null, path.node.body),
);
},
ExportNamedDeclaration: {
@ -254,8 +254,8 @@ export function getMarkoFile(code, fileOpts, markoOpts) {
file.opts.filename,
file.code,
node.errorLoc || node.loc,
node.label
)
node.label,
),
);
}
});
@ -396,4 +396,7 @@ function isMarkoOutput(output) {
function finalizeMeta(meta) {
meta.watchFiles = [...new Set(meta.watchFiles)];
if (meta.analyzedTags) {
meta.analyzedTags = [...new Set(meta.analyzedTags)];
}
}

View File

@ -1,5 +1,3 @@
import { TagType, createParser } from "htmljs-parser";
import * as t from "../babel-types";
import {
getTagDefForTagName,
parseArgs,
@ -7,8 +5,12 @@ import {
parseParams,
parseStatements,
parseTemplateLiteral,
parseTypeArgs,
parseTypeParams,
parseVar,
} from "@marko/babel-utils";
import { TagType, createParser } from "htmljs-parser";
import * as t from "../babel-types";
const noop = () => {};
const emptyRange = (part) => part.start === part.end;
@ -73,7 +75,7 @@ export function parseMarko(file) {
file,
parser.read(value),
value.start,
value.end
value.end,
);
if (t.isStringLiteral(result)) {
// convert to template literal just so that we don't mistake it for a native tag if this is a tag name.
@ -84,7 +86,7 @@ export function parseMarko(file) {
cooked: result.value,
}),
],
[]
[],
);
} else {
return result;
@ -197,6 +199,22 @@ export function parseMarko(file) {
onComment(part) {
pushContent(withLoc(t.markoComment(parser.read(part.value)), part));
},
onTagTypeArgs(part) {
currentTag.node.typeArguments = parseTypeArgs(
file,
parser.read(part.value),
part.value.start,
part.value.end,
);
},
onTagTypeParams(part) {
currentBody.node.typeParameters = parseTypeParams(
file,
parser.read(part.value),
part.value.start,
part.value.end,
);
},
onPlaceholder(part) {
pushContent(
withLoc(
@ -205,12 +223,12 @@ export function parseMarko(file) {
file,
parser.read(part.value),
part.value.start,
part.value.end
part.value.end,
),
part.escape
part.escape,
),
part
)
part,
),
);
},
onScriptlet(part) {
@ -221,11 +239,11 @@ export function parseMarko(file) {
file,
parser.read(part.value),
part.value.start,
part.value.end
)
part.value.end,
),
),
part
)
part,
),
);
},
onOpenTagName(part) {
@ -241,13 +259,13 @@ export function parseMarko(file) {
if (literalTagName === "%") {
throw file.buildCodeFrameError(
tagName,
"<% scriptlets %> are no longer supported."
"<% scriptlets %> are no longer supported.",
);
}
const parseOptions = (node.tagDef = getTagDefForTagName(
file,
literalTagName
literalTagName,
))?.parseOptions;
if (parseOptions) {
@ -284,7 +302,7 @@ export function parseMarko(file) {
file,
parser.read(value),
value.start,
value.end
value.end,
);
},
@ -293,7 +311,7 @@ export function parseMarko(file) {
file,
parser.read(value),
value.start,
value.end
value.end,
);
},
@ -302,7 +320,7 @@ export function parseMarko(file) {
file,
parser.read(value),
value.start,
value.end
value.end,
);
},
@ -315,8 +333,8 @@ export function parseMarko(file) {
t.booleanLiteral(true),
modifier,
undefined,
!name
))
!name,
)),
);
currentAttr.start = part.start;
@ -328,7 +346,7 @@ export function parseMarko(file) {
file,
parser.read(value),
value.start,
value.end
value.end,
);
currentAttr.end = end;
@ -340,7 +358,7 @@ export function parseMarko(file) {
currentAttr.value = parseExpression(
file,
parser.read(part.value),
part.value.start
part.value.start,
);
},
@ -353,18 +371,18 @@ export function parseMarko(file) {
file,
parser.read(part.params.value),
part.params.value.start,
part.params.value.end
part.params.value.end,
),
t.blockStatement(
parseStatements(
file,
parser.read(part.body.value),
part.body.value.start,
part.body.value.end
)
)
part.body.value.end,
),
),
),
part
part,
);
},
@ -373,10 +391,10 @@ export function parseMarko(file) {
currentTag.node.attributes.push(
withLoc(
t.markoSpreadAttribute(
parseExpression(file, parser.read(part.value), part.value.start)
parseExpression(file, parser.read(part.value), part.value.start),
),
part
)
part,
),
);
},
@ -392,20 +410,22 @@ export function parseMarko(file) {
currentShorthandClassNames.length === 1
? currentShorthandClassNames[0]
: currentShorthandClassNames.every((expr) =>
t.isStringLiteral(expr)
)
? withLoc(
t.stringLiteral(
currentShorthandClassNames.map((node) => node.value).join(" ")
),
{
start: currentShorthandClassNames[0].start,
end: currentShorthandClassNames[
currentShorthandClassNames.length - 1
].end,
}
)
: t.arrayExpression(currentShorthandClassNames);
t.isStringLiteral(expr),
)
? withLoc(
t.stringLiteral(
currentShorthandClassNames
.map((node) => node.value)
.join(" "),
),
{
start: currentShorthandClassNames[0].start,
end: currentShorthandClassNames[
currentShorthandClassNames.length - 1
].end,
},
)
: t.arrayExpression(currentShorthandClassNames);
for (const attr of attributes) {
if (attr.name === "class") {
@ -443,12 +463,12 @@ export function parseMarko(file) {
if (attr.name === "id") {
throw file.buildCodeFrameError(
attr,
"Cannot have shorthand id and id attribute."
"Cannot have shorthand id and id attribute.",
);
}
}
currentTag.node.attributes.push(
t.markoAttribute("id", currentShorthandId)
t.markoAttribute("id", currentShorthandId),
);
currentShorthandId = undefined;
}

View File

@ -1,18 +1,8 @@
import "../types/patch";
import Printer from "@babel/generator/lib/printer";
import * as t from "@babel/types";
import SELF_CLOSING from "self-closing-tags";
import Printer from "@babel/generator/lib/printer";
const UNENCLOSED_WHITESPACE_TYPES = [
"LogicalExpression",
"AssignmentExpression",
"ConditionalExpression",
"BinaryExpression",
"NewExpression",
"Function",
"AssignmentExpression",
];
Object.assign(Printer.prototype, {
MarkoParseError(node) {
@ -61,7 +51,10 @@ Object.assign(Printer.prototype, {
this.token(`${node.static ? "static" : "$"} `);
if (node.body.length === 1) {
if (
node.body.length === 1 &&
!statementCouldHaveUnenclosedNewline(node.body[0])
) {
// TODO should determine if node has unenclosed newlines.
this.print(node.body[0], node);
} else {
@ -171,6 +164,12 @@ Object.assign(Printer.prototype, {
this.token(tagName);
}
if (node.typeArguments) {
this.token("<");
this.printList(node.typeArguments.params, node);
this.token(">");
}
if (node.var) {
this.token("/");
this.print(node.var, node);
@ -187,6 +186,14 @@ Object.assign(Printer.prototype, {
}
if (node.body.params.length) {
if (node.body.typeParameters) {
if (!node.typeArguments) {
this.token(" ");
}
this.token("<");
this.printList(node.body.typeParameters.params, node);
this.token(">");
}
this.token("|");
this.printList(node.body.params, node);
this.token("|");
@ -228,7 +235,7 @@ function spaceSeparator() {
}
function printWithParansIfNeeded(value, parent) {
const needsParans = hasUnenclosedWhitespace(value);
const needsParans = expressionCouldHaveUnenclosedWhitespace(value);
if (needsParans) {
this.token("(");
@ -241,6 +248,25 @@ function printWithParansIfNeeded(value, parent) {
}
}
function hasUnenclosedWhitespace(node) {
return UNENCLOSED_WHITESPACE_TYPES.includes(node.type);
function expressionCouldHaveUnenclosedWhitespace(node) {
switch (node.type) {
case "AssignmentExpression":
case "BinaryExpression":
case "ConditionalExpression":
case "Function":
case "LogicalExpression":
case "NewExpression":
return true;
default:
return false;
}
}
function statementCouldHaveUnenclosedNewline(node) {
switch (node.type) {
case "VariableDeclaration":
return node.declarations.length > 1;
default:
return false;
}
}

View File

@ -1,7 +1,7 @@
import "../types/patch";
import * as t from "@babel/types";
import traverse, { NodePath, Scope } from "@babel/traverse";
import * as t from "@babel/types";
import { MARKO_ALIAS_TYPES, MARKO_TYPES } from "../types/definitions";
MARKO_TYPES.forEach((typeName) => {
@ -75,7 +75,7 @@ Scope.prototype.crawl = function () {
}
}
},
})
}),
);
}
@ -95,7 +95,7 @@ Scope.prototype.crawl = function () {
if (hoistableBinding) {
if (hoistableBinding === true) {
throw ref.buildCodeFrameError(
"Ambiguous reference, variable was defined in multiple places and was not shadowed."
"Ambiguous reference, variable was defined in multiple places and was not shadowed.",
);
}

View File

@ -118,7 +118,7 @@ const MarkoDefinitions = {
arguments: {
validate: chain(
assertValueType("array"),
assertEach(assertNodeType("Expression", "SpreadElement"))
assertEach(assertNodeType("Expression", "SpreadElement")),
),
optional: true,
},
@ -147,15 +147,19 @@ const MarkoDefinitions = {
MarkoTagBody: {
aliases: ["Marko", "BlockParent", "Scope"],
builder: ["body", "params"],
visitor: ["params", "body"],
visitor: ["typeParameters", "params", "body"],
fields: {
params: {
validate: chain(
assertValueType("array"),
assertEach(assertNodeType("Identifier", "Pattern", "RestElement"))
assertEach(assertNodeType("Identifier", "Pattern", "RestElement")),
),
default: [],
},
typeParameters: {
validate: assertNodeType("TSTypeParameterDeclaration"),
optional: true,
},
body: {
validate: arrayOfType([
"MarkoTag",
@ -173,7 +177,14 @@ const MarkoDefinitions = {
MarkoTag: {
aliases: ["Marko", "Statement"],
builder: ["name", "attributes", "body", "arguments", "var"],
visitor: ["name", "attributes", "body", "arguments", "var"],
visitor: [
"name",
"typeArguments",
"attributes",
"body",
"arguments",
"var",
],
fields: {
name: {
validate: assertNodeType("Expression"),
@ -188,10 +199,14 @@ const MarkoDefinitions = {
arguments: {
validate: chain(
assertValueType("array"),
assertEach(assertNodeType("Expression", "SpreadElement"))
assertEach(assertNodeType("Expression", "SpreadElement")),
),
optional: true,
},
typeArguments: {
validate: assertNodeType("TSTypeParameterInstantiation"),
optional: true,
},
rawValue: {
validate: assertValueType("string"),
optional: true,
@ -208,6 +223,6 @@ export default MarkoDefinitions;
export const MARKO_TYPES = Object.keys(MarkoDefinitions);
export const MARKO_ALIAS_TYPES = Array.from(
new Set(
MARKO_TYPES.reduce((all, t) => all.concat(MarkoDefinitions[t].aliases), [])
)
MARKO_TYPES.reduce((all, t) => all.concat(MarkoDefinitions[t].aliases), []),
),
);

View File

@ -1,9 +1,9 @@
/* eslint-disable no-import-assign */
import * as babelTypes from "@babel/types";
import defineType from "@babel/types/lib/definitions/utils";
import validate from "@babel/types/lib/validators/validate";
import * as generatedValidators from "@babel/types/lib/validators/generated";
import * as referencedValidators from "@babel/types/lib/validators/isReferenced";
import validate from "@babel/types/lib/validators/validate";
import definitions, { MARKO_ALIAS_TYPES, MARKO_TYPES } from "./definitions";
const {
@ -64,8 +64,8 @@ function assert(typeName, node, opts) {
if (!is(typeName, node, opts)) {
throw new Error(
`Expected type "${typeName}" with option ${JSON.stringify(
opts
)}, but instead got "${node.type}".`
opts,
)}, but instead got "${node.type}".`,
);
}
}
@ -76,7 +76,7 @@ function builder(type, args) {
const countArgs = args.length;
if (countArgs > keys.length) {
throw new Error(
`${type}: Too many arguments passed. Received ${countArgs} but can receive no more than ${keys.length}`
`${type}: Too many arguments passed. Received ${countArgs} but can receive no more than ${keys.length}`,
);
}

View File

@ -136,6 +136,12 @@ const config = {
hydrateIncludeImports:
/\.(css|less|s[ac]ss|styl|png|jpe?g|gif|svg|ico|webp|avif|mp4|webm|ogg|mp3|wav|flac|aac|woff2?|eot|ttf|otf)$/,
/**
* When compiling in hydrate mode, this option will cause the compiler to
* call the `marko/components.init` function to begin hydrating components.
*/
hydrateInit: true,
/**
* Set to true in order to bring in the hot module replacement runtime.
*/

View File

@ -1,17 +1,17 @@
export * as types from "./babel-types";
import path from "path";
import * as babel from "@babel/core";
import cjsPlugin from "@babel/plugin-transform-modules-commonjs";
import tsSyntaxPlugin from "@babel/plugin-syntax-typescript";
import cjsPlugin from "@babel/plugin-transform-modules-commonjs";
import tsTransformPlugin from "@babel/plugin-transform-typescript";
import { DiagnosticType } from "@marko/babel-utils";
import corePlugin from "./babel-plugin";
import defaultConfig from "./config";
import * as taglib from "./taglib";
import shouldOptimize from "./util/should-optimize";
import tryLoadTranslator from "./util/try-load-translator";
import { buildCodeFrameError } from "./util/build-code-frame";
import throwAggregateError from "./util/merge-errors";
import shouldOptimize from "./util/should-optimize";
import tryLoadTranslator from "./util/try-load-translator";
export { taglib };
const CWD = process.cwd();
@ -23,7 +23,7 @@ export function configure(newConfig) {
export async function compile(src, filename, config) {
const markoConfig = loadMarkoConfig(config);
const babelConfig = loadBabelConfig(filename, markoConfig);
const babelConfig = await loadBabelConfig(filename, markoConfig);
const babelResult = await babel.transformAsync(src, babelConfig);
scheduleDefaultClear(markoConfig);
return buildResult(src, filename, markoConfig.errorRecovery, babelResult);
@ -31,7 +31,7 @@ export async function compile(src, filename, config) {
export function compileSync(src, filename, config) {
const markoConfig = loadMarkoConfig(config);
const babelConfig = loadBabelConfig(filename, markoConfig);
const babelConfig = loadBabelConfigSync(filename, markoConfig);
const babelResult = babel.transformSync(src, babelConfig);
scheduleDefaultClear(markoConfig);
return buildResult(src, filename, markoConfig.errorRecovery, babelResult);
@ -73,7 +73,21 @@ function loadMarkoConfig(config) {
return markoConfig;
}
function loadBabelConfig(filename, { babelConfig, ...markoConfig }) {
async function loadBabelConfig(filename, config) {
const baseBabelConfig = getBaseBabelConfig(filename, config);
return isTranslatedOutput(config.output)
? (await babel.loadPartialConfigAsync(baseBabelConfig)).options
: baseBabelConfig;
}
function loadBabelConfigSync(filename, config) {
const baseBabelConfig = getBaseBabelConfig(filename, config);
return isTranslatedOutput(config.output)
? babel.loadPartialConfigSync(baseBabelConfig).options
: baseBabelConfig;
}
function getBaseBabelConfig(filename, { babelConfig, ...markoConfig }) {
const isTranslated = isTranslatedOutput(markoConfig.output);
const requiredPlugins = [
[corePlugin, markoConfig],
@ -111,8 +125,6 @@ function loadBabelConfig(filename, { babelConfig, ...markoConfig }) {
if (markoConfig.modules === "cjs") {
baseBabelConfig.plugins.push([cjsPlugin, { loose: true }]);
}
return babel.loadPartialConfig(baseBabelConfig).options;
}
return baseBabelConfig;

View File

@ -1,7 +1,7 @@
"use strict";
const compiler = require(".");
const shouldOptimize = require("./util/should-optimize").default;
const compiler = require(".");
const requiredOptions = { modules: "cjs" };
const isDev = !shouldOptimize();
const sourceMaps = new Map();
@ -35,8 +35,8 @@ function register({ extensions = require.extensions, ...options } = {}) {
sourceMaps: isDev ? "both" : false,
},
options,
requiredOptions
)
requiredOptions,
),
);
if (compiled.map) {

View File

@ -1,9 +1,9 @@
"use strict";
var nodePath = require("path");
var lassoPackageRoot = require("lasso-package-root");
var resolveFrom = require("resolve-from").silent;
var taglibConfig = require("../config");
var taglibLoader = require("../loader");
var lassoPackageRoot = require("lasso-package-root");
var findCache = {};
var excludedDirs = {};
var excludedPackages = {};
@ -117,10 +117,10 @@ function find(dirname, registeredTaglibs) {
if (!excludedPackages[name]) {
let taglibPath = resolveFrom(
rootPkg.__dirname,
nodePath.join(name, "marko.json")
nodePath.join(name, "marko.json"),
);
if (taglibPath) {
var taglib = taglibLoader.loadTaglibFromFile(taglibPath);
var taglib = taglibLoader.loadTaglibFromFile(taglibPath, true);
helper.addTaglib(taglib);
}
}

View File

@ -1,15 +1,17 @@
import loader from "./loader";
import finder from "./finder";
import Lookup from "./lookup";
import taglibConfig from "./config";
import path from "path";
import markoModules from "../../modules";
import tryLoadTranslator from "../util/try-load-translator";
import taglibConfig from "./config";
import finder from "./finder";
import loader from "./loader";
import Lookup from "./lookup";
export const excludeDir = finder.excludeDir;
export const excludePackage = finder.excludePackage;
import markoHTMLTaglib from "./marko-html.json";
import markoSVGTaglib from "./marko-svg.json";
import markoMathTaglib from "./marko-math.json";
import markoSVGTaglib from "./marko-svg.json";
const registeredTaglibs = [];
const loadedTranslatorsTaglibs = new Map();
@ -23,7 +25,7 @@ export function buildLookup(dirname, requestedTranslator, onError) {
const translator = tryLoadTranslator(requestedTranslator);
if (!translator || !Array.isArray(translator.taglibs)) {
throw new Error(
"@marko/compiler: Invalid translator provided to buildLookup(dir, translator)"
"@marko/compiler: Invalid translator provided to buildLookup(dir, translator)",
);
}
@ -33,8 +35,8 @@ export function buildLookup(dirname, requestedTranslator, onError) {
loadedTranslatorsTaglibs.set(
translator,
(taglibsForDir = registeredTaglibs.concat(
translator.taglibs.map(([id, props]) => loadTaglib(id, props))
))
translator.taglibs.map(([id, props]) => loadTaglib(id, props)),
)),
);
}
@ -77,6 +79,22 @@ export function buildLookup(dirname, requestedTranslator, onError) {
}
export function register(id, props) {
if (typeof props === "undefined") {
switch (id[0]) {
case ".":
case "/":
case "\\":
break;
default:
if (!id.endsWith(".json")) {
id = path.join(id, "marko.json");
}
break;
}
id = markoModules.require.resolve(id);
props = markoModules.require(id);
}
registeredTaglibs.push(loadTaglib(id, props));
}

View File

@ -26,9 +26,10 @@ function handleImport(taglib, importedTaglib) {
}
class Taglib {
constructor(filePath) {
constructor(filePath, isFromPackageJson) {
ok(filePath, '"filePath" expected');
this.filePath = this.path /* deprecated */ = this.id = filePath;
this.isFromPackageJson = isFromPackageJson === true;
this.dirname = path.dirname(this.filePath);
this.scriptLang = undefined;
this.tags = {};
@ -47,7 +48,7 @@ class Taglib {
if (!attribute.pattern && !attribute.name) {
throw new Error(
"Invalid attribute: " + require("util").inspect(attribute)
"Invalid attribute: " + require("util").inspect(attribute),
);
}

View File

@ -1,15 +1,15 @@
var cache = require("./cache");
var types = require("./types");
var loaders = require("./loaders");
var DependencyChain = require("./DependencyChain");
var loaders = require("./loaders");
var types = require("./types");
function loadTaglibFromProps(taglib, taglibProps) {
return loaders.loadTaglibFromProps(taglib, taglibProps);
}
function loadTaglibFromFile(filePath) {
return loaders.loadTaglibFromFile(filePath);
function loadTaglibFromFile(filePath, isFromPackageJson) {
return loaders.loadTaglibFromFile(filePath, isFromPackageJson);
}
function loadTaglibFromDir(filePath) {
@ -29,7 +29,7 @@ function loadTag(tagProps, filePath) {
loaders.loadTagFromProps(
tag,
tagProps,
new DependencyChain(filePath ? [filePath] : [])
new DependencyChain(filePath ? [filePath] : []),
);
return tag;
}

View File

@ -1,5 +1,5 @@
var stripJsonComments = require("@luxass/strip-json-comments").strip;
var taglibConfig = require("../config");
var stripJsonComments = require("strip-json-comments");
var fsReadOptions = { encoding: "utf8" };
exports.readFileSync = function (path) {
@ -10,7 +10,7 @@ exports.readFileSync = function (path) {
return taglibProps;
} catch (e) {
throw new Error(
'Unable to parse JSON file at path "' + path + '". Error: ' + e
'Unable to parse JSON file at path "' + path + '". Error: ' + e,
);
}
};

View File

@ -2,9 +2,9 @@
var assert = require("assert");
var raptorRegexp = require("raptor-regexp");
var createError = require("raptor-util/createError");
var propertyHandlers = require("./property-handlers");
var types = require("./types");
var createError = require("raptor-util/createError");
var hasOwnProperty = Object.prototype.hasOwnProperty;
class AttrLoader {
@ -229,7 +229,7 @@ function loadAttributeFromProps(attrName, attrProps, dependencyChain) {
dependencyChain +
"): " +
err,
err
err,
);
}

View File

@ -10,7 +10,7 @@ module.exports = function loadAttributes(value, parent, dependencyChain) {
var attr = loaders.loadAttributeFromProps(
attrName,
attrProps,
dependencyChain.append("@" + attrName)
dependencyChain.append("@" + attrName),
);
parent.addAttribute(attr);

View File

@ -1,9 +1,8 @@
var jsonFileReader = require("./json-file-reader");
var types = require("./types");
var cache = require("./cache");
var loaders = require("./loaders");
var ok = require("assert").ok;
var cache = require("./cache");
var jsonFileReader = require("./json-file-reader");
var loaders = require("./loaders");
var types = require("./types");
function loadTagFromFile(filePath) {
ok(filePath, '"filePath" is required');

View File

@ -1,21 +1,39 @@
"use strict";
var ok = require("assert").ok;
var resolveFrom = require("resolve-from").silent;
var propertyHandlers = require("./property-handlers");
var isObjectEmpty = require("raptor-util/isObjectEmpty");
var nodePath = require("path");
var createError = require("raptor-util/createError");
var taglibConfig = require("../config");
var types = require("./types");
var loaders = require("./loaders");
var isObjectEmpty = require("raptor-util/isObjectEmpty");
var resolveFrom = require("resolve-from").silent;
var markoModules = require("../../../modules");
var taglibConfig = require("../config");
var loaders = require("./loaders");
var propertyHandlers = require("./property-handlers");
var types = require("./types");
var hasOwnProperty = Object.prototype.hasOwnProperty;
function resolveRelative(dirname, value) {
return value[0] === "." ? resolveFrom(dirname, value) : value;
}
function resolveWithMarkoExt(dirname, value) {
if (value[0] !== ".") return value;
if (
markoModules.require.extensions &&
!(".marko" in markoModules.require.extensions)
) {
markoModules.require.extensions[".marko"] = undefined;
try {
return resolveFrom(dirname, value);
} finally {
delete markoModules.require.extensions[".marko"];
}
}
return resolveFrom(dirname, value);
}
function removeDashes(str) {
return str.replace(/-([a-z])/g, function (match, lower) {
return lower.toUpperCase();
@ -105,14 +123,14 @@ class TagLoader {
nestedVariable.nameFromAttribute = value;
},
},
dependencyChain.toString()
dependencyChain.toString(),
);
if (!nestedVariable.name && !nestedVariable.nameFromAttribute) {
throw new Error(
'The "name" or "name-from-attribute" attribute is required for a nested variable (' +
dependencyChain +
")"
")",
);
}
}
@ -203,7 +221,7 @@ class TagLoader {
// with the user's taglib.
if (!isObjectEmpty(value)) {
throw new Error(
"Unsupported properties of [" + Object.keys(value).join(", ") + "]"
"Unsupported properties of [" + Object.keys(value).join(", ") + "]",
);
}
@ -240,7 +258,7 @@ class TagLoader {
var attr = loaders.loadAttributeFromProps(
attrName,
attrProps,
dependencyChain.append(part)
dependencyChain.append(part),
);
tag.addAttribute(attr);
@ -271,7 +289,7 @@ class TagLoader {
let attr = loaders.loadAttributeFromProps(
nestedTag.targetProperty,
{ type: "object" },
dependencyChain.append(part)
dependencyChain.append(part),
);
tag.addAttribute(attr);
@ -300,7 +318,7 @@ class TagLoader {
* @param {String} value The renderer path
*/
renderer(value) {
this.tag.renderer = resolveRelative(this.dirname, value);
this.tag.renderer = resolveWithMarkoExt(this.dirname, value);
}
/**
@ -349,7 +367,7 @@ class TagLoader {
loaders.loadAttributes(
value,
tag,
this.dependencyChain.append("attributes")
this.dependencyChain.append("attributes"),
);
}
@ -474,7 +492,7 @@ class TagLoader {
for (const nestedTagName in value) {
const nestedTagDef = value[nestedTagName];
var dependencyChain = this.dependencyChain.append(
`nestedTags["${nestedTagName}"]`
`nestedTags["${nestedTagName}"]`,
);
var nestedTag = new types.Tag(filePath);
@ -482,16 +500,13 @@ class TagLoader {
nestedTag.name = nestedTagName;
tag.addNestedTag(nestedTag);
if (!nestedTag.isRepeated) {
let attr = loaders.loadAttributeFromProps(
tag.addAttribute(
loaders.loadAttributeFromProps(
nestedTag.targetProperty,
{ type: "object" },
dependencyChain
);
tag.addAttribute(attr);
}
{ type: "expression" },
dependencyChain,
),
);
}
}
@ -556,7 +571,7 @@ function loadTagFromProps(tag, tagProps, dependencyChain) {
} catch (err) {
throw createError(
"Unable to load tag (" + dependencyChain + "): " + err,
err
err,
);
}

View File

@ -1,10 +1,9 @@
var ok = require("assert").ok;
var nodePath = require("path");
var types = require("./types");
var cache = require("./cache");
var DependencyChain = require("./DependencyChain");
var scanTagsDir = require("./scanTagsDir");
var ok = require("assert").ok;
var types = require("./types");
function loadFromDir(dir) {
ok(dir, '"dir" is required');
@ -22,7 +21,7 @@ function loadFromDir(dir) {
dir,
"components",
taglib,
new DependencyChain([componentsPath])
new DependencyChain([componentsPath]),
);
}

View File

@ -1,11 +1,10 @@
var jsonFileReader = require("./json-file-reader");
var types = require("./types");
var cache = require("./cache");
var loaders = require("./loaders");
var ok = require("assert").ok;
var cache = require("./cache");
var jsonFileReader = require("./json-file-reader");
var loaders = require("./loaders");
var types = require("./types");
function loadFromFile(filePath) {
function loadFromFile(filePath, isFromPackageJson) {
ok(filePath, '"filePath" is required');
var taglib = cache.get(filePath);
@ -13,7 +12,7 @@ function loadFromFile(filePath) {
// Only load a taglib once by caching the loaded taglibs using the file
// system file path as the key
if (!taglib) {
taglib = new types.Taglib(filePath);
taglib = new types.Taglib(filePath, isFromPackageJson);
cache.put(filePath, taglib);
var taglibProps = jsonFileReader.readFileSync(filePath);

View File

@ -1,17 +1,17 @@
"use strict";
var ok = require("assert").ok;
var resolveFrom = require("resolve-from").silent;
var nodePath = require("path");
var types = require("./types");
var taglibFS = require("../config");
var scanTagsDir = require("./scanTagsDir");
var propertyHandlers = require("./property-handlers");
var jsonFileReader = require("./json-file-reader");
var DependencyChain = require("./DependencyChain");
var createError = require("raptor-util/createError");
var loaders = require("./loaders");
var resolveFrom = require("resolve-from").silent;
var markoModules = require("../../../modules");
var taglibFS = require("../config");
var DependencyChain = require("./DependencyChain");
var jsonFileReader = require("./json-file-reader");
var loaders = require("./loaders");
var propertyHandlers = require("./property-handlers");
var scanTagsDir = require("./scanTagsDir");
var types = require("./types");
var hasOwnProperty = Object.prototype.hasOwnProperty;
function resolveRelative(dirname, value) {
@ -44,7 +44,7 @@ class TaglibLoader {
constructor(taglib, dependencyChain) {
ok(
dependencyChain instanceof DependencyChain,
'"dependencyChain" is not valid'
'"dependencyChain" is not valid',
);
this.dependencyChain = dependencyChain;
@ -105,7 +105,7 @@ class TaglibLoader {
tagFilePath +
'" does not exist. (' +
dependencyChain +
")"
")",
);
}
@ -142,7 +142,7 @@ class TaglibLoader {
var attr = loaders.loadAttributeFromProps(
attrKey,
value,
this.dependencyChain.append("@" + attrKey)
this.dependencyChain.append("@" + attrKey),
);
attr.filePath = filePath;
@ -176,7 +176,7 @@ class TaglibLoader {
var attr = loaders.loadAttributeFromProps(
attrName,
attrDef,
this.dependencyChain.append("@" + attrName)
this.dependencyChain.append("@" + attrName),
);
attr.key = attrName;
@ -205,7 +205,7 @@ class TaglibLoader {
this._handleTag(
tagName,
tags[tagName],
this.dependencyChain.append("tags." + tagName)
this.dependencyChain.append("tags." + tagName),
);
}
}
@ -237,7 +237,7 @@ class TaglibLoader {
dirname,
dir[i],
taglib,
this.dependencyChain.append(`tags-dir[${i}]`)
this.dependencyChain.append(`tags-dir[${i}]`),
);
}
} else {
@ -246,12 +246,30 @@ class TaglibLoader {
dirname,
dir,
taglib,
this.dependencyChain.append(`tags-dir`)
this.dependencyChain.append(`tags-dir`),
);
}
}
}
exports(dir) {
var taglib = this.taglib;
var path = this.filePath;
var dirname = this.dirname;
if (taglib.isFromPackageJson) {
taglib.tagsDir = false;
scanTagsDir(
path,
dirname,
dir,
taglib,
this.dependencyChain.append(`exports`),
);
}
}
taglibImports(imports) {
// The "taglib-imports" property allows another taglib to be imported
// into this taglib so that the tags defined in the imported taglib
@ -282,7 +300,7 @@ class TaglibLoader {
importPath = resolveFrom(
packageDir,
nodePath.join(dependencyName, "marko.json")
nodePath.join(dependencyName, "marko.json"),
);
if (importPath) {
@ -296,7 +314,7 @@ class TaglibLoader {
taglib.addImport(importPath);
} else {
throw new Error(
"Import not found: " + curImport + " (from " + dirname + ")"
"Import not found: " + curImport + " (from " + dirname + ")",
);
}
}
@ -381,7 +399,7 @@ class TaglibLoader {
let attr = loaders.loadAttributeFromProps(
attrName,
rawAttrDef,
attrGroupDependencyChain.append("@" + attrName)
attrGroupDependencyChain.append("@" + attrName),
);
attrGroup[attrName] = attr;
@ -406,7 +424,7 @@ function loadTaglibFromProps(taglib, taglibProps, dependencyChain) {
} catch (err) {
throw createError(
"Unable to load taglib (" + dependencyChain + "): " + err,
err
err,
);
}

View File

@ -57,7 +57,7 @@ module.exports = function invokeHandlers(config, handlers, path) {
"Invalid option of " +
badProperty +
". Allowed: " +
Object.keys(handlers).join(", ")
Object.keys(handlers).join(", "),
);
}

View File

@ -117,7 +117,7 @@ module.exports = function scanTagsDir(
tagsConfigDirname,
dir,
taglib,
dependencyChain
dependencyChain,
) {
let prefix;
@ -179,7 +179,7 @@ module.exports = function scanTagsDir(
"Invalid tag file: " +
tagJsonPath +
". Neither a renderer or a template was found for tag. " +
JSON.stringify(tagDef, null, 2)
JSON.stringify(tagDef, null, 2),
);
} else {
// Skip this directory... there doesn't appear to be anything in it

View File

@ -1,8 +1,8 @@
"use strict";
var ok = require("assert").ok;
var taglibTypes = require("../loader/types");
var extend = require("raptor-util/extend");
var taglibTypes = require("../loader/types");
var hasOwnProperty = Object.prototype.hasOwnProperty;
function TAG_COMPARATOR(a, b) {
@ -27,8 +27,8 @@ function merge(target, source) {
target[key] = Array.isArray(targetVal)
? targetVal.concat(sourceVal)
: Array.isArray(sourceVal)
? [targetVal].concat(sourceVal)
: merge(merge(new targetVal.constructor(), targetVal), sourceVal);
? [targetVal].concat(sourceVal)
: merge(merge(new targetVal.constructor(), targetVal), sourceVal);
continue;
}
}

View File

@ -1,6 +1,6 @@
import path from "path";
import color from "kleur";
import { codeFrameColumns } from "@babel/code-frame";
import color from "kleur";
const CWD = process.cwd();
const indent = " ";
@ -12,7 +12,7 @@ class CompileError extends Error {
this.stack = loc
? `CompileError\n${indent}at ${prettyFileName}\n${prettyMessage.replace(
/^/gm,
indent
indent,
)}`
: `CompileError: ${prettyMessage}\n${indent}at ${prettyFileName}`;
@ -71,7 +71,7 @@ function buildMessage(code, loc, message) {
}
: undefined,
},
{ highlightCode: true, message }
{ highlightCode: true, message },
)
: message;
}

View File

@ -1,5 +1,257 @@
# Change Log
## 5.32.5
### Patch Changes
- [#2076](https://github.com/marko-js/marko/pull/2076) [`69b3ff5`](https://github.com/marko-js/marko/commit/69b3ff57c829418946e05c13b644a5560f589086) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Upgrade all package deps to latest
- Updated dependencies [[`69b3ff5`](https://github.com/marko-js/marko/commit/69b3ff57c829418946e05c13b644a5560f589086)]:
- @marko/translator-default@5.31.11
- @marko/compiler@5.34.4
## 5.32.4
### Patch Changes
- [#2074](https://github.com/marko-js/marko/pull/2074) [`bf23c566fac02f4e2991be357a95483663493b3f`](https://github.com/marko-js/marko/commit/bf23c566fac02f4e2991be357a95483663493b3f) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Upgrade package lock and built types.
- Updated dependencies [[`bf23c566fac02f4e2991be357a95483663493b3f`](https://github.com/marko-js/marko/commit/bf23c566fac02f4e2991be357a95483663493b3f)]:
- @marko/translator-default@5.31.10
- @marko/compiler@5.34.3
## 5.32.3
### Patch Changes
- [#2071](https://github.com/marko-js/marko/pull/2071) [`652b7aa16`](https://github.com/marko-js/marko/commit/652b7aa1608ace877e713ce43486fca1b0a0400b) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Fix types for onsecuritypolicyviolation native attribute.
- [#2071](https://github.com/marko-js/marko/pull/2071) [`652b7aa16`](https://github.com/marko-js/marko/commit/652b7aa1608ace877e713ce43486fca1b0a0400b) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Fix types for <await> tag attribute tags.
## 5.32.2
### Patch Changes
- [#2069](https://github.com/marko-js/marko/pull/2069) [`977d69078`](https://github.com/marko-js/marko/commit/977d690784f1d97acb3494bb822fa852c1380685) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Fix issue with printing variable declarations with multiple variables.
- Updated dependencies [[`977d69078`](https://github.com/marko-js/marko/commit/977d690784f1d97acb3494bb822fa852c1380685)]:
- @marko/translator-default@5.31.9
- @marko/compiler@5.34.2
## 5.32.1
### Patch Changes
- [#2067](https://github.com/marko-js/marko/pull/2067) [`ea859a547`](https://github.com/marko-js/marko/commit/ea859a547972be7a2fde6688890023c5bc85bc16) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Simplify the typings of Marko.NativeTags to work better across typescript versions.
## 5.32.0
### Minor Changes
- [#2062](https://github.com/marko-js/marko/pull/2062) [`436ace040`](https://github.com/marko-js/marko/commit/436ace040b73d11908911d60c10845b6e99e8eca) Thanks [@LuLaValva](https://github.com/LuLaValva)! - Add "exports" to marko.json
### Patch Changes
- Updated dependencies [[`436ace040`](https://github.com/marko-js/marko/commit/436ace040b73d11908911d60c10845b6e99e8eca)]:
- @marko/compiler@5.34.0
## 5.31.18
### Patch Changes
- [#2060](https://github.com/marko-js/marko/pull/2060) [`648a94928`](https://github.com/marko-js/marko/commit/648a94928f662b04634a61395d5d48a956a8ff36) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Expose meta data about which child Marko templates were analyzed for a given compilation.
- Updated dependencies [[`648a94928`](https://github.com/marko-js/marko/commit/648a94928f662b04634a61395d5d48a956a8ff36), [`aed88284b`](https://github.com/marko-js/marko/commit/aed88284b8b3c68965f70b6bdf9412c7100c5df5)]:
- @marko/compiler@5.33.8
- @marko/translator-default@5.31.8
## 5.31.17
### Patch Changes
- [#2056](https://github.com/marko-js/marko/pull/2056) [`84f443d60`](https://github.com/marko-js/marko/commit/84f443d60539cc1b3382c6b16da4061070f97aca) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Fix issue when the Marko hot-reload runtime is loaded in native esm
- Updated dependencies [[`84f443d60`](https://github.com/marko-js/marko/commit/84f443d60539cc1b3382c6b16da4061070f97aca)]:
- @marko/translator-default@5.31.7
- @marko/compiler@5.33.7
## 5.31.16
### Patch Changes
- [#2054](https://github.com/marko-js/marko/pull/2054) [`1c5eccadf`](https://github.com/marko-js/marko/commit/1c5eccadf8d968552dbe8756905009107d783718) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Fix regression with @marko/babel-utils not exposing new parse helpers.
- Updated dependencies [[`1c5eccadf`](https://github.com/marko-js/marko/commit/1c5eccadf8d968552dbe8756905009107d783718)]:
- @marko/compiler@5.33.6
- @marko/translator-default@5.31.6
## 5.31.15
### Patch Changes
- [#2053](https://github.com/marko-js/marko/pull/2053) [`37b347eb5`](https://github.com/marko-js/marko/commit/37b347eb5e9e2d16badb170a880e2eed5d2892a9) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Improve compatibility of legacy Marko widgets loading a template compiled as esm.
- Updated dependencies [[`5354d4411`](https://github.com/marko-js/marko/commit/5354d44112c56fcbbd7f44dd3bf91be1e5a7747c)]:
- @marko/translator-default@5.31.5
- @marko/compiler@5.33.5
## 5.31.14
### Patch Changes
- [#2049](https://github.com/marko-js/marko/pull/2049) [`1554b1e1e`](https://github.com/marko-js/marko/commit/1554b1e1e53a75980af0b238cc27bed5ddfa215a) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Allow `template.marko` to act as `index.marko` for backword compat with v4/v3.
- Updated dependencies [[`1554b1e1e`](https://github.com/marko-js/marko/commit/1554b1e1e53a75980af0b238cc27bed5ddfa215a)]:
- @marko/translator-default@5.31.4
- @marko/compiler@5.33.4
## 5.31.13
### Patch Changes
- [#2046](https://github.com/marko-js/marko/pull/2046) [`b7cefe4c6`](https://github.com/marko-js/marko/commit/b7cefe4c6f000fc01008ac5d75d2054a34f4f574) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Lazily check for global jQuery when patching legacy components.
## 5.31.12
### Patch Changes
- [#2042](https://github.com/marko-js/marko/pull/2042) [`447104632`](https://github.com/marko-js/marko/commit/44710463258999ad037febef10264e32f3291157) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - When compiling async, prefer using the async babel api for loading babel config files.
- [#2044](https://github.com/marko-js/marko/pull/2044) [`358fb2d22`](https://github.com/marko-js/marko/commit/358fb2d22e3e7bd7cba5e97f34547ff53c309f62) Thanks [@LuLaValva](https://github.com/LuLaValva)! - fix event handler types
- [#2043](https://github.com/marko-js/marko/pull/2043) [`f94486b10`](https://github.com/marko-js/marko/commit/f94486b10fb8c7be63551d0aa4cbebdb8d03614b) Thanks [@LuLaValva](https://github.com/LuLaValva)! - Add CSS camelCase properties
- Updated dependencies [[`447104632`](https://github.com/marko-js/marko/commit/44710463258999ad037febef10264e32f3291157)]:
- @marko/compiler@5.33.3
## 5.31.11
### Patch Changes
- [#2040](https://github.com/marko-js/marko/pull/2040) [`a5e3f0461`](https://github.com/marko-js/marko/commit/a5e3f046135bcdd054426974282d4ba870bdb97c) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Fix compat issue where markoWidgets.defineRenderer was not resolving the default export of a Marko 5 template.
## 5.31.10
### Patch Changes
- [#2038](https://github.com/marko-js/marko/pull/2038) [`71a227a5f`](https://github.com/marko-js/marko/commit/71a227a5ff8b16c0bb983e082f28280518f712ce) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Fix issue where using the longhand nested attribute tag syntax in a marko.json with a `target-property` defined was not registering the alias as a known attribute, leading to compile errors.
- Updated dependencies [[`71a227a5f`](https://github.com/marko-js/marko/commit/71a227a5ff8b16c0bb983e082f28280518f712ce)]:
- @marko/translator-default@5.31.3
- @marko/compiler@5.33.2
## 5.31.9
### Patch Changes
- [#2036](https://github.com/marko-js/marko/pull/2036) [`ea08cc2a9`](https://github.com/marko-js/marko/commit/ea08cc2a9bb494d5735dc0fe69b6aa85cb5ed179) Thanks [@rturnq](https://github.com/rturnq)! - Simplify batching, prevent treeshaking bug
## 5.31.8
### Patch Changes
- [#2034](https://github.com/marko-js/marko/pull/2034) [`a340023b7`](https://github.com/marko-js/marko/commit/a340023b7ef59f1af9ad80f42ac69138ddd3d216) Thanks [@LuLaValva](https://github.com/LuLaValva)! - docs(concise-mode): add multiline attributes
## 5.31.7
### Patch Changes
- [#2032](https://github.com/marko-js/marko/pull/2032) [`034f96741`](https://github.com/marko-js/marko/commit/034f967419d840ae7b8a8cead6c657d5cc64b0a6) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Add js file extension to compiled import of the registry runtime. This improves prebundling in Vite.
- Updated dependencies [[`034f96741`](https://github.com/marko-js/marko/commit/034f967419d840ae7b8a8cead6c657d5cc64b0a6)]:
- @marko/translator-default@5.31.2
## 5.31.6
### Patch Changes
- [#2027](https://github.com/marko-js/marko/pull/2027) [`db819d388`](https://github.com/marko-js/marko/commit/db819d388e9419d7354a9639c59faa0cd3518305) Thanks [@mlrawlings](https://github.com/mlrawlings)! - Update Marko 5 Upgrade instructions
## 5.31.5
### Patch Changes
- [#2024](https://github.com/marko-js/marko/pull/2024) [`085c87387`](https://github.com/marko-js/marko/commit/085c8738701146877958d81f88248cdf67678174) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Avoid using the bare webpack include api to check if a module has already been loaded.
## 5.31.4
### Patch Changes
- [#2020](https://github.com/marko-js/marko/pull/2020) [`6a4e947b5`](https://github.com/marko-js/marko/commit/6a4e947b5ac9944e61d7871d314a6325a0522d1d) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Ensure .marko files are resolved for legacy renderer taglib configs.
- Updated dependencies [[`6a4e947b5`](https://github.com/marko-js/marko/commit/6a4e947b5ac9944e61d7871d314a6325a0522d1d)]:
- @marko/compiler@5.33.1
- @marko/translator-default@5.31.1
## 5.31.3
### Patch Changes
- [#2018](https://github.com/marko-js/marko/pull/2018) [`7a22dc3d1`](https://github.com/marko-js/marko/commit/7a22dc3d16b0d9da9abc7b62c9aa917e54738a16) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Fix loading of legacy components in some test environments.
## 5.31.2
### Patch Changes
- [#2016](https://github.com/marko-js/marko/pull/2016) [`fb46f0a91`](https://github.com/marko-js/marko/commit/fb46f0a9186a0b437e011b40fecf975eae0b9093) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Optimize preserve-tag implementation to use browser remap again.
- [#2016](https://github.com/marko-js/marko/pull/2016) [`1b1df3f56`](https://github.com/marko-js/marko/commit/1b1df3f5674e09914bca448f045ff720002c3ae6) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Fix issue where marko-widger renderers were not bound to the correct "this".
## 5.31.1
### Patch Changes
- [#2014](https://github.com/marko-js/marko/pull/2014) [`636ae526d`](https://github.com/marko-js/marko/commit/636ae526d7f58fa9fe21b0d9e30beb711258002c) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Avoid bundling load api when using legacy runtime.
- [#2014](https://github.com/marko-js/marko/pull/2014) [`636ae526d`](https://github.com/marko-js/marko/commit/636ae526d7f58fa9fe21b0d9e30beb711258002c) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Avoid loading legacy Marko compiler api if possible when using load api.
## 5.31.0
### Minor Changes
- [#2012](https://github.com/marko-js/marko/pull/2012) [`9aede281f`](https://github.com/marko-js/marko/commit/9aede281f95a788df03d607b7d6ca10d9025d39f) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Add compiler option to disable initializing components when outputting hydrate code.
### Patch Changes
- [#2012](https://github.com/marko-js/marko/pull/2012) [`17099cd8f`](https://github.com/marko-js/marko/commit/17099cd8ff4ef5868b79f32bdb682fd7393e7139) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Allow skipping output of virtual dependencies by returning a falsey value from the `resolveVirtualDependency` option.
- [#2012](https://github.com/marko-js/marko/pull/2012) [`ec21e799f`](https://github.com/marko-js/marko/commit/ec21e799f39e74c3d5b0fcfb5839a3954fbc7ad0) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Fix issue where data (legacy alias of input) was overwritten by assignment but still being migrated.
- Updated dependencies [[`9aede281f`](https://github.com/marko-js/marko/commit/9aede281f95a788df03d607b7d6ca10d9025d39f), [`17099cd8f`](https://github.com/marko-js/marko/commit/17099cd8ff4ef5868b79f32bdb682fd7393e7139), [`ec21e799f`](https://github.com/marko-js/marko/commit/ec21e799f39e74c3d5b0fcfb5839a3954fbc7ad0), [`6ba268c84`](https://github.com/marko-js/marko/commit/6ba268c841631b3ed36964c8f532e543885ad4f5)]:
- @marko/translator-default@5.31.0
- @marko/compiler@5.33.0
## 5.30.2
### Patch Changes
- [#2010](https://github.com/marko-js/marko/pull/2010) [`c08f940c8`](https://github.com/marko-js/marko/commit/c08f940c8ea73806ed79d35d435b3844fbfb6759) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Improve upgrade guide to reference the new `marko-widgets` and `@marko/compat-v4` modules.
## 5.30.1
### Patch Changes
- [#2008](https://github.com/marko-js/marko/pull/2008) [`1235cf700`](https://github.com/marko-js/marko/commit/1235cf7005447bdad7a84bacf20d40c7c457c03a) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Fix regression with static template literal expressions.
- Updated dependencies [[`1235cf700`](https://github.com/marko-js/marko/commit/1235cf7005447bdad7a84bacf20d40c7c457c03a)]:
- @marko/translator-default@5.30.1
## 5.30.0
### Minor Changes
- [#2006](https://github.com/marko-js/marko/pull/2006) [`b2e70bc45`](https://github.com/marko-js/marko/commit/b2e70bc45006a8cccfa61ac99bbca40a71d05fd1) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Add compute node helper to replace babels `evaluate` helper. This helper is less aggressive and doesn't suffer from the false positives that popped up with babels version.
### Patch Changes
- [#2005](https://github.com/marko-js/marko/pull/2005) [`4286236b0`](https://github.com/marko-js/marko/commit/4286236b0eaa3cfdbdde02f531d76fcaed3203ee) Thanks [@rturnq](https://github.com/rturnq)! - Handle errors thrown in await catch attribute
- [#2006](https://github.com/marko-js/marko/pull/2006) [`b2e70bc45`](https://github.com/marko-js/marko/commit/b2e70bc45006a8cccfa61ac99bbca40a71d05fd1) Thanks [@DylanPiercey](https://github.com/DylanPiercey)! - Avoid adding trailing semicolon to style attribute output.
- Updated dependencies [[`b2e70bc45`](https://github.com/marko-js/marko/commit/b2e70bc45006a8cccfa61ac99bbca40a71d05fd1), [`b2e70bc45`](https://github.com/marko-js/marko/commit/b2e70bc45006a8cccfa61ac99bbca40a71d05fd1), [`d45962db1`](https://github.com/marko-js/marko/commit/d45962db1def9b025a1d75d98b4c655c0565e3ef)]:
- @marko/translator-default@5.30.0
- @marko/compiler@5.32.0
## 5.29.2
### Patch Changes
@ -2725,8 +2977,8 @@ Summary of changes across all beta releases for the `4.5.0` release:
```javascript
require("marko/node-require").install({
compilerOptions: {
writeToDisk: false
}
writeToDisk: false,
},
});
```
@ -3381,9 +3633,9 @@ exports.renderer = function (input, out) {
template.render(
{
tabs: tabs
tabs: tabs,
},
out
out,
);
};
```

View File

@ -5,35 +5,7 @@
var fs = require("fs");
var nodePath = require("path");
var cwd = process.cwd();
var resolveFrom = require("resolve-from").silent;
// Try to use the Marko compiler installed with the project
var markoCompilerPath = resolveFrom(process.cwd(), "marko/compiler");
const markocPkgVersion = require("../package.json").version;
var markoPkgPath = resolveFrom(process.cwd(), "marko/package.json");
var markoPkgVersion = markoPkgPath && require(markoPkgPath).version;
var markoCompiler = markoCompilerPath
? require(markoCompilerPath)
: require("../compiler");
var Minimatch = require("minimatch").Minimatch;
var appModulePath = require("app-module-path");
var mmOptions = {
matchBase: true,
dot: true,
flipNegate: true,
};
function relPath(path) {
if (path.startsWith(cwd)) {
return path.substring(cwd.length + 1);
}
}
var args = require("argly")
.createParser({
"--help": {
@ -94,7 +66,7 @@ var args = require("argly")
.example("Compile multiple templates", "$0 template.marko src/ foo/")
.example(
"Delete all *.marko.js files in the current directory",
"$0 . --clean"
"$0 . --clean",
)
.validate(function (result) {
if (result.help) {
@ -124,6 +96,31 @@ var args = require("argly")
process.exit(1);
})
.parse();
var Minimatch = require("minimatch").Minimatch;
var resolveFrom = require("resolve-from").silent;
// Try to use the Marko compiler installed with the project
var markoCompilerPath = resolveFrom(process.cwd(), "marko/compiler");
const markocPkgVersion = require("../package.json").version;
var markoPkgPath = resolveFrom(process.cwd(), "marko/package.json");
var markoPkgVersion = markoPkgPath && require(markoPkgPath).version;
var markoCompiler = markoCompilerPath
? require(markoCompilerPath)
: require("../compiler");
var mmOptions = {
matchBase: true,
dot: true,
flipNegate: true,
};
function relPath(path) {
if (path.startsWith(cwd)) {
return path.substring(cwd.length + 1);
}
}
var output = "html";
@ -324,7 +321,7 @@ if (args.clean) {
} else {
console.log("Deleted " + deleteCount + " file(s)");
}
}
},
);
} else {
var found = {};
@ -345,7 +342,7 @@ if (args.clean) {
relPath(path) +
"\n Output: " +
relPath(outPath) +
"\n"
"\n",
);
context.beginAsync();
@ -356,7 +353,7 @@ if (args.clean) {
'Failed to compile "' +
relPath(path) +
'". Error: ' +
(err.stack || err)
(err.stack || err),
);
context.endAsync(err);
return;
@ -367,7 +364,7 @@ if (args.clean) {
fs.writeFile(outPath, src, "utf8", function (err) {
if (err) {
failed.push(
'Failed to write "' + path + '". Error: ' + (err.stack || err)
'Failed to write "' + path + '". Error: ' + (err.stack || err),
);
context.endAsync(err);
return;
@ -384,7 +381,7 @@ if (args.clean) {
'Failed to write sourcemap"' +
path +
'". Error: ' +
(err.stack || err)
(err.stack || err),
);
context.endAsync(err);
return;
@ -392,7 +389,7 @@ if (args.clean) {
compileCount++;
context.endAsync();
}
},
);
return;
@ -426,7 +423,7 @@ if (args.clean) {
if (err) {
if (failed.length) {
console.error(
"The following errors occurred:\n- " + failed.join("\n- ")
"The following errors occurred:\n- " + failed.join("\n- "),
);
} else {
console.error(err);
@ -440,7 +437,7 @@ if (args.clean) {
} else {
console.log("Compiled " + compileCount + " templates(s)");
}
}
},
);
}
}

View File

@ -261,7 +261,7 @@ http
count: 30,
colors: ["red", "green", "blue"],
},
res
res,
);
})
.listen(8080);

View File

@ -782,7 +782,7 @@ Marko uses [`listener-tracker`](https://github.com/patrick-steele-idem/listener-
```js
this.subscribeTo(window).on("scroll", () =>
console.log("The user scrolled the window!")
console.log("The user scrolled the window!"),
);
```

View File

@ -70,7 +70,7 @@ import * as compiler from "@marko/compiler";
const asyncResult = await compiler.compile(
"<h1>Hello!</>",
"./src/index.marko",
{ modules: "cjs" }
{ modules: "cjs" },
);
const syncResult = compiler.compileSync("<h1>Hello!</>", "./src/index.marko", {
modules: "cjs",
@ -217,7 +217,7 @@ Type:
code: string;
virtualPath: string;
map?: SourceMap;
}
},
) => string;
```
@ -296,6 +296,12 @@ import "./baz.wasm";
For `hydrate` output, with the default `hydrateIncludeImports`, would only cause `./foo.css` to be loaded in the browser.
#### `hydrateInit`
This option is only used for `output: "hydrate"`. It defaults to `true` and causes the hydrate output to include code which tells the Marko runtime to begin hydrating any registered components.
Setting to false will disable that `init` call and allow you to generate code which _just_ imports any hydrate dependencies for a template.
#### `cache`
Type: typeof [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) (specifically, `.get()` is required)<br>

View File

@ -38,6 +38,28 @@ _output.html_
> **ProTip:** These shorthand attributes are available within the HTML syntax as well
## Attributes on multiple lines
If a component has lots of attributes, you can spread them across multiple lines by surrounding them with square brackets
_input.marko_
```marko
div [
id="hello"
class=["class1", "class2", "class3"]
style={ border: "1px solid red" }
] -- hello
```
_output.html_
```html
<div id="hello" class="class1 class2 class3" style="border:1px solid red">
hello
</div>
```
## Text
Text in concise mode is denoted by two or more dashes (`--`).

View File

@ -19,7 +19,7 @@ server.on("request", (req, res) => {
count: 30,
colors: ["red", "green", "blue"],
},
res
res,
);
});

View File

@ -38,7 +38,7 @@ npm install @lasso/marko-taglib
After installing, the lasso custom tags can be used in your templates:
```html
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />

View File

@ -6,59 +6,106 @@ This means you should complete a step and get it merged back into master fairly
If you do decide to pause and later jump in where you left off, be sure to repeat Step 0 first 😉.
## Step 0 - Ensure you're in a working state
Run your application and tests to ensure your project is in a working state. There's little worse than finding an issue after you've started the upgrade process only to figure out the issue existed beforehand.
## Step 1 - Upgrade to latest 4.x
## Step 0 - Ensure you're in a working state on the latest version of Marko 4
Before we start, you'll want to make sure that you are already on the latest `4.x` release of `marko`.
```
```bash
# Upgrade using npm
npm install marko@^4
```
or
```
# Or with yarn
yarn upgrade marko@^4
```
> Note: Do NOT run `npm install marko` (without the `@^4`). This will put you on Marko 5 and we're not quite there yet.
> **Warning**
> Do _not_ run `npm install marko` (without the `@^4`). This will put you on Marko 5 and we're not quite there yet.
## Step 2 - Deal with deprecations
Run your application and tests to ensure your project is in a working state. There's little worse than finding an issue after you've started the upgrade process only to figure out the issue existed beforehand.
Run your application and tests and ensure that there are no deprecation warnings logged to the console. If there are, you should follow the instructions in the deprecation messages to avoid the deprecated pattern and migrate to the recommended pattern.
Additionally, any deprecation warnings that start with `MIGRATION` are automatically migratable by [`marko migrate`](https://github.com/marko-js/cli/blob/master/packages/migrate/README.md). Most migrations are 100% safe and will run automatically. However, there are a few migrations which are considered unsafe: they may only get you 90% of the way there. These migrations will prompt and ask if you want to run the migration. It is highly recommended to run these only on a single component at a time and then finish the migration manually using the guide below so that your app is always in a working state.
## Step 3 - Upgrade dependencies
## Step 1 - Upgrade dependencies
Before upgrading to Marko 5, it is recommended to make sure that your Marko-related dependencies are up-to-date. Many packages have versions that support both Marko 4 and Marko 5. If one of your dependencies doesn't have a version that supports both, you'll need to wait to upgrade it until you're upgrading Marko.
After upgrading, run your application and tests to ensure that everything is still working as intended. If there are any issues, please refer to the changelogs of the modules you just upgraded to see if you need to make any changes within your app to accommodate the new versions.
## Step 4 - Upgrade marko
## Step 2 - Upgrade Marko
Phew! With all the prep out of the way we're finally ready to upgrade `marko`!
```
npm install marko@^5
### Install Modules
Note that some features removed in Marko 4 do not log deprecations since they do not need to be resolved to get up and running with Marko 5. However for Marko 5 to support some of the features removed after Marko 4 you need to install a `compat` module.
There are currently two `compat` modules you can install, one which supports the `marko-widget`'s api from Marko@3 and one with just the compat needed for Marko@4 components.
**For apps with `marko-widgets` installed, add the following modules:**
```bash
# Upgrade using npm
npm install marko@^5 @marko/compiler marko-widgets@^8
# Or with yarn
yarn install marko@^5 @marko/compiler marko-widgets@^8
```
or
**For apps which were not using the Marko@3 compat layer, add the following modules:**
```
yarn upgrade marko@^5
```bash
# Upgrade using npm
npm install marko@^5 @marko/compiler @marko/compat-v4
# Or with yarn
yarn install marko@^5 @marko/compiler @marko/compat-v4
```
> **Note**: Marko 5 has changed to using ES Modules. This means if you are using CJS modules to `require` a Marko template you will need to use the `.default` property exported.
>
> ```js
> const template = require("./template.marko");
> // …should become:
> const template = require("./template.marko").default;
>
> // If already using ES Modules, things remain the same:
> import template from "./template.marko";
> ```
### App entry updates
If you're bundling your server code (common with `webpack` setups), your entry will be your bundler config.
Otherwise it's probably something like `index.js` or `server.js` near your project root.
- Register your compat module globally so that any dependencies also run through the compat layer:
```js
require("@marko/compiler").taglib.register("marko-widgets");
```
> **Note**
> if using `webpack` or `rollup` this line should also be added you your bundler config file
> **Note**
> if using `jest` you should pass the [`register` option](https://github.com/marko-js/jest#customizing-the-marko-compiler) which requires the latest version of `jest` and `@marko/jest`
- _If you're using `babel`_, Marko 5 picks up on your babel config which could change behavior. You may want to configure Marko to ignore your babel config:
```js
require("@marko/compiler").configure({
babelConfig: {
babelrc: false,
configFile: false,
},
});
```
If you do this, you'll also want also want to pass the `babelConfig` option to your bundler plugin (`lasso-marko`, `@marko/webpack`, `@marko/rollup`)
### Submodule updates
A couple submodules no longer exist in Marko 5:
- _If you're using the require hook_, replace `marko/node-require`:
```diff
- require('marko/node-require').install();
+ require('@marko/compiler/register');
```
- _If you're using `browser-refresh`_, including the runtime is no longer necessary:
```diff
- require('marko/browser-refresh').enable();
```
## Step 3 - Optional, but recommended: deal with deprecations
Run your application and tests and ensure that there are no deprecation warnings logged to the console. If there are, you should follow the instructions in the deprecation messages to avoid the deprecated pattern and migrate to the recommended pattern.
Additionally, any deprecation warnings that start with `MIGRATION` are automatically migratable by [`marko migrate`](https://github.com/marko-js/cli/blob/master/packages/migrate/README.md). Most migrations are 100% safe and will run automatically. However, there are a few migrations which are considered unsafe: they may only get you 90% of the way there. These migrations will prompt and ask if you want to run the migration. It is highly recommended to run these only on a single component at a time and then finish the migration manually using the guide below so that your app is always in a working state.
> **Note**
> The [TagsAPI](https://dev.to/ryansolid/introducing-the-marko-tags-api-preview-37o4) is becoming stable soon. Deprecations related to `marko-widgets`, might be worth holding off on rather than migrating these widgets to the Class Components API.

View File

@ -131,6 +131,7 @@ Similar to [`marko-tag.json`](#single-component-definition), this file is discov
```js
{
"taglib-id": "my-custom-tag-library", // Names the component library, for better errors.
"exports": "./dist", // Where to export the compiled components.
"tags-dir": "./ui-modules", // What directory to crawl to autodiscover components. Default:`./components/`
"taglib-imports": ["./some-folder/marko.json", "./other-folder/marko.json"], // Creates a _combined_ tag library by referencing others.

View File

@ -643,7 +643,7 @@ import ReactDOM from "react-dom";
ReactDOM.render(
<HelloMessage name="John" />,
document.getElementById("container")
document.getElementById("container"),
);
```

View File

@ -258,7 +258,7 @@ app.get("/", (req, res) => {
},
},
},
res
res,
);
});
```

View File

@ -118,7 +118,7 @@ export default (async () => [
},
external: (id) =>
externalDependencies.some(
(dependency) => id === dependency || id.startsWith(dependency + "/")
(dependency) => id === dependency || id.startsWith(dependency + "/"),
),
plugins: [isWatch && runPlugin({ execArgv: ["--enable-source-maps"] })],
}),
@ -167,8 +167,8 @@ export default (async () => [
`📊 Bundle visualizer at \x1b[4;36mfile://${path.join(
__dirname,
"../../",
bundleAnalyzerFilename
)}\x1b[0m`
bundleAnalyzerFilename,
)}\x1b[0m`,
);
},
},
@ -345,7 +345,7 @@ marko.browser({
fileName,
// only inline code chunks below 1kB
inline: code.trim().length < 1024 && code,
}
},
);
},
});

View File

@ -113,7 +113,7 @@ function render(input, out) {
}),
},
0,
4
4,
);
}
```

View File

@ -58,11 +58,11 @@ declare global {
once(eventName: PropertyKey, listener: (...args: any[]) => any): this;
prependListener(
eventName: PropertyKey,
listener: (...args: any[]) => any
listener: (...args: any[]) => any,
): this;
removeListener(
eventName: PropertyKey,
listener: (...args: any[]) => any
listener: (...args: any[]) => any,
): this;
/** Register a callback executed when the last async out has completed. */
onLast(listener: (next: () => void) => unknown): this;
@ -84,7 +84,7 @@ declare global {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
in Params extends readonly any[] = [],
// eslint-disable-next-line @typescript-eslint/no-unused-vars
out Return = void
out Return = void,
> {}
/** Valid data types which can be passed in as a <${dynamic}/> tag name. */
@ -125,7 +125,7 @@ declare global {
* cleaned up once this component is destroyed
* */
subscribeTo(
emitter: unknown
emitter: unknown,
): Omit<Emitter, "listenerCount" | "prependListener" | "emit">;
/** Emits an event on the component instance. */
emit(eventName: PropertyKey, ...args: any[]): boolean;
@ -136,12 +136,12 @@ declare global {
/** Listen to an event on the component instance before all other listeners. */
prependListener(
eventName: PropertyKey,
listener: (...args: any[]) => any
listener: (...args: any[]) => any,
): this;
/** Remove a listener from the component instance. */
removeListener(
eventName: PropertyKey,
listener: (...args: any[]) => any
listener: (...args: any[]) => any,
): this;
/** Remove all listeners from the component instance. */
removeAllListeners(eventName?: PropertyKey): this;
@ -156,14 +156,14 @@ declare global {
/** Gets an element reference by its `key` attribute in the template. */
getEl<T extends Element | void = Element | void>(
key?: string,
index?: number
index?: number,
): T;
/** Gets all element references by their `key` attribute in the template. */
getEls<T extends Element[] = Element[]>(key: string): T;
/** Gets a component reference by its `key` attribute in the template. */
getComponent<T extends Component | void = Component | void>(
key: string,
index?: number
index?: number,
): T;
/** Gets all component references by their `key` attribute in the template. */
getComponents<T extends Component[] = Component[]>(key: string): T;
@ -178,14 +178,14 @@ declare global {
*/
setState<Key extends PropertyKey>(
name: Key & keyof this["state"],
value: (this["state"] & Record<PropertyKey, unknown>)[Key]
value: (this["state"] & Record<PropertyKey, unknown>)[Key],
): void;
setState(value: Partial<this["state"]>): void;
/** Schedules an update related to a specific state property and optionally updates the value. */
setStateDirty<Key extends PropertyKey>(
name: Key & keyof this["state"],
value?: (this["state"] & Record<PropertyKey, unknown>)[Key]
value?: (this["state"] & Record<PropertyKey, unknown>)[Key],
): void;
/** Synchronously flush any scheduled updates. */
update(): void;
@ -238,7 +238,7 @@ declare global {
stream?: {
write: (chunk: string) => void;
end: (chunk?: string) => void;
}
},
): Marko.Out<Marko.Component>;
/** Asynchronously render the template in buffered mode. */
@ -246,13 +246,13 @@ declare global {
input: Marko.TemplateInput<Input>,
cb?: (
err: Error | null,
result: Marko.RenderResult<Marko.Component>
) => void
result: Marko.RenderResult<Marko.Component>,
) => void,
): Marko.Out<Marko.Component>;
/** Synchronously render the template. */
abstract renderSync(
input: Marko.TemplateInput<Input>
input: Marko.TemplateInput<Input>,
): Marko.RenderResult<Marko.Component>;
/** Synchronously render a template to a string. */
@ -260,13 +260,13 @@ declare global {
/** Render a template and return a stream.Readable in nodejs or a ReadableStream in a web worker environment. */
abstract stream(
input: Marko.TemplateInput<Input>
input: Marko.TemplateInput<Input>,
): ReadableStream<string> & NodeJS.ReadableStream;
/** @marko-overload-end */
}
export interface RenderResult<
out Component extends Marko.Component = Marko.Component
out Component extends Marko.Component = Marko.Component,
> {
/** Returns the component created as a result of rendering the template. */
getComponent(): Component;
@ -307,11 +307,11 @@ declare global {
once(eventName: PropertyKey, listener: (...args: any[]) => any): this;
prependListener(
eventName: PropertyKey,
listener: (...args: any[]) => any
listener: (...args: any[]) => any,
): this;
removeListener(
eventName: PropertyKey,
listener: (...args: any[]) => any
listener: (...args: any[]) => any,
): this;
removeAllListeners(eventName?: PropertyKey): this;
}
@ -323,7 +323,7 @@ declare global {
export interface NativeTag<
Input extends Record<string, any>,
Return extends Element
Return extends Element,
> {
input: Input;
return: () => Return;
@ -335,37 +335,37 @@ declare global {
export type Input<Name> = 0 extends 1 & Name
? any
: Name extends string
? Name extends keyof NativeTags
? NativeTags[Name]["input"]
: Record<string, unknown>
: Name extends
| Template<infer Input, any>
| { _(): () => (input: infer Input) => any }
? Input
: Name extends Body<infer Args, any>
? Args extends {
length: infer Length;
}
? number extends Length
? { value?: Args }
: 0 extends Length
? { value?: [] }
: { value: Args }
: never
: never;
? Name extends keyof NativeTags
? NativeTags[Name]["input"]
: Record<string, unknown>
: Name extends
| Template<infer Input, any>
| { _(): () => (input: infer Input) => any }
? Input
: Name extends Body<infer Args, any>
? Args extends {
length: infer Length;
}
? number extends Length
? { value?: Args }
: 0 extends Length
? { value?: [] }
: { value: Args }
: never
: never;
export type Return<Name> = 0 extends 1 & Name
? any
: Name extends string
? Name extends keyof NativeTags
? NativeTags[Name]["return"]
: () => Element
: Name extends
| { _(): () => (input: any) => { return: infer Return } }
| Template<any, infer Return>
| Body<any, infer Return>
? Return
: never;
? Name extends keyof NativeTags
? NativeTags[Name]["return"]
: () => Element
: Name extends
| { _(): () => (input: any) => { return: infer Return } }
| Template<any, infer Return>
| Body<any, infer Return>
? Return
: never;
/** @deprecated @see {@link Marko.Input} */
export type NativeTagInput<Name extends keyof NativeTags> =

View File

@ -0,0 +1,15 @@
<module-code(function(require, opts) {
var file = `"./${opts.optimize ? "dist" : "src"}/runtime/components/legacy"`;
if (opts.modules === "cjs") {
return `module.exports = require(${file});\n`;
} else {
return `export { default } from ${file};\nexport * from ${file};\n`;
}
})/>
// What's going on here? We are using Marko to do JavaScript code generation
// during the module bundling phase to conditionally export either the
// "src" or the "dist" folder based on whether or not we are doing a
// debug or non-debug build. We are using Marko since we know the Marko compiler
// is enabled already (no extra babel transform required).

View File

@ -0,0 +1,7 @@
var isDebug = require("./env").isDebug;
if (isDebug) {
module.exports = require("./src/runtime/components/legacy");
} else {
module.exports = require("./dist/runtime/components/legacy");
}

View File

@ -1,6 +1,6 @@
{
"name": "marko",
"version": "5.29.2",
"version": "5.32.5",
"description": "UI Components + streaming, async, high performance, HTML templating for Node.js and the browser.",
"keywords": [
"front-end",
@ -35,6 +35,7 @@
"browser": {
"./compiler.js": "./compiler-browser.marko",
"./components.js": "./components-browser.marko",
"./legacy-components.js": "./legacy-components-browser.marko",
"./index.js": "./index-browser.marko"
},
"types": "index.d.ts",
@ -50,6 +51,8 @@
"compiler.js",
"components-browser.marko",
"components.js",
"legacy-components-browser.marko",
"legacy-components.js",
"env.js",
"index.d.ts",
"index-browser.marko",
@ -61,20 +64,20 @@
"build": "babel ./src --out-dir ./dist --delete-dir-on-start --copy-files --config-file ../../babel.config.js --env-name=production"
},
"dependencies": {
"@marko/compiler": "^5.30.0",
"@marko/translator-default": "^5.28.0",
"@marko/compiler": "^5.34.4",
"@marko/translator-default": "^5.31.11",
"app-module-path": "^2.2.0",
"argly": "^1.2.0",
"browser-refresh-client": "1.1.4",
"complain": "^1.6.0",
"csstype": "^3.1.2",
"csstype": "^3.1.3",
"events-light": "^1.0.5",
"listener-tracker": "^2.0.0",
"minimatch": "^3.0.4",
"minimatch": "^9.0.3",
"raptor-util": "^3.2.0",
"resolve-from": "^5.0.0",
"self-closing-tags": "^1.0.1",
"warp10": "^2.0.1"
"warp10": "^2.1.0"
},
"logo": {
"url": "https://raw.githubusercontent.com/marko-js/branding/master/marko-logo-small.png"

View File

@ -1,12 +1,12 @@
"use strict";
var ok = require("assert").ok;
var fs = require("fs");
var complain = "MARKO_DEBUG" && require("complain");
var compiler = require("@marko/compiler");
var extend = require("raptor-util/extend");
var globalConfig = require("./config");
var ok = require("assert").ok;
var fs = require("fs");
var taglib = require("../taglib");
var globalConfig = require("./config");
var defaults = extend({}, globalConfig);
// eslint-disable-next-line no-constant-condition
@ -16,7 +16,7 @@ if ("MARKO_DEBUG") {
require.main.filename !== require.resolve("../../bin/markoc")
) {
complain(
"Using `marko/compiler` has been deprecated, please upgrade to the `@marko/compiler` module."
"Using `marko/compiler` has been deprecated, please upgrade to the `@marko/compiler` module.",
);
}
}
@ -67,7 +67,7 @@ function _compile(src, filename, userConfig, callback) {
if (callback) {
compiler.compile(src, filename, options).then(
(result) => callback(null, resultCompat(result, options)),
(error) => callback(error)
(error) => callback(error),
);
} else {
return resultCompat(compiler.compileSync(src, filename, options), options);
@ -98,7 +98,7 @@ function compileForBrowser(src, filename, options, callback) {
meta: false,
sourceOnly: false,
},
options
options,
);
return compile(src, filename, options, callback);

View File

@ -1,81 +1 @@
var ComponentsContext = require("../../runtime/components/ComponentsContext");
var getComponentsContext = ComponentsContext.___getComponentsContext;
module.exports = function render(input, out) {
var isComponent = !input.n;
var shouldPreserve = !("i" in input) || input.i;
var componentsContext = out.___components;
if (typeof document === "object") {
var isHydrate =
componentsContext && componentsContext.___globalContext.___isHydrate;
var ownerComponent = out.___assignedComponentDef.___component;
var referenceComponent = ownerComponent;
var key = out.___assignedKey;
var checkKey = key;
if (key[0] !== "@") {
var parentComponent = componentsContext.___componentDef.___component;
if (ownerComponent !== parentComponent) {
referenceComponent = parentComponent;
checkKey += ":" + ownerComponent.id;
}
}
var isPreserved =
shouldPreserve &&
(isHydrate || referenceComponent.___keyedElements[checkKey]);
if (isComponent) {
out.bf(key, ownerComponent, shouldPreserve);
if (!isPreserved && input.renderBody) {
input.renderBody(out);
}
out.ef();
} else {
if (isPreserved) {
if (input.b) {
out.___parent.___preserveBody = true;
} else {
out.beginElement("", null, key, ownerComponent);
out.___parent.___preserve = true;
out.endElement();
}
} else if (input.renderBody) {
input.renderBody(out);
}
}
} else {
if (isComponent) {
out.bf(
out.___assignedKey,
out.___assignedComponentDef.___component,
true
);
}
if (input.renderBody) {
if (shouldPreserve) {
var parentPreserved = false;
if (componentsContext) {
parentPreserved = componentsContext.___isPreserved;
} else {
componentsContext = getComponentsContext(out);
}
componentsContext.___isPreserved = true;
input.renderBody(out);
componentsContext.___isPreserved = parentPreserved;
} else {
input.renderBody(out);
}
}
if (isComponent) {
out.ef();
}
}
};
module.exports = require("@internal/preserve-tag");

View File

@ -98,7 +98,7 @@ AsyncValue.prototype = {
},
function onRejected(err) {
queueMicrotask(asyncValue.___reject.bind(asyncValue, err));
}
},
);
if (finalPromise.done) {

View File

@ -8,7 +8,7 @@ function $af(
childNodes,
i,
len,
af
af,
) {
af = $af;

View File

@ -1,8 +1,8 @@
export interface Input<T> {
value: readonly [T];
then?: { renderBody: Marko.Body<[Awaited<T>]> };
catch?: { renderBody: Marko.Body<[unknown]> };
placeholder?: { renderBody: Marko.Body };
then?: Marko.AttrTag<{ renderBody: Marko.Body<[Awaited<T>]> }>;
catch?: Marko.AttrTag<{ renderBody: Marko.Body<[unknown]> }>;
placeholder?: Marko.AttrTag<{ renderBody: Marko.Body }>;
"client-reorder"?: boolean;
name?: string;
timeout?: number;

View File

@ -18,7 +18,7 @@ function requestData(provider, timeout) {
if ("MARKO_DEBUG") {
complain(
"Passing a callback function to the <await> tag has been deprecated, please use a promise instead.",
{ level: 1, locationIndex: 3 }
{ level: 1, locationIndex: 3 },
);
}
@ -220,7 +220,11 @@ function renderContents(err, data, input, out) {
if (err) {
if (input.catch) {
if (errorRenderer) {
errorRenderer(out, err);
try {
errorRenderer(out, err);
} catch (err2) {
out.error(err2);
}
}
} else {
out.error(err);

View File

@ -52,7 +52,7 @@ module.exports = function (input, out) {
if (!global._afRuntime) {
// Minified version of ./client-reorder-runtime.js
asyncOut.script(
`function $af(d,a,e,l,g,h,k,b,f,c){c=$af;if(a&&!c[a])(c[a+="$"]||(c[a]=[])).push(d);else{e=document;l=e.getElementById("af"+d);g=e.getElementById("afph"+d);h=e.createDocumentFragment();k=l.childNodes;b=0;for(f=k.length;b<f;b++)h.appendChild(k.item(0));g&&g.parentNode.replaceChild(h,g);c[d]=1;if(a=c[d+"$"])for(b=0,f=a.length;b<f;b++)c(a[b])}}`
`function $af(d,a,e,l,g,h,k,b,f,c){c=$af;if(a&&!c[a])(c[a+="$"]||(c[a]=[])).push(d);else{e=document;l=e.getElementById("af"+d);g=e.getElementById("afph"+d);h=e.createDocumentFragment();k=l.childNodes;b=0;for(f=k.length;b<f;b++)h.appendChild(k.item(0));g&&g.parentNode.replaceChild(h,g);c[d]=1;if(a=c[d+"$"])for(b=0,f=a.length;b<f;b++)c(a[b])}}`,
);
global._afRuntime = true;
}
@ -70,7 +70,7 @@ module.exports = function (input, out) {
awaitInfo.id +
'">' +
result.toString() +
"</div>"
"</div>",
);
} else {
asyncOut.write(
@ -78,7 +78,7 @@ module.exports = function (input, out) {
awaitInfo.id +
'" style="display:none">' +
result.toString() +
"</div>"
"</div>",
);
}
@ -88,7 +88,7 @@ module.exports = function (input, out) {
? awaitInfo.id
: '"' + awaitInfo.id + '"') +
(awaitInfo.after ? ',"' + awaitInfo.after + '"' : "") +
")"
")",
);
awaitInfo.out.writer = asyncOut.writer;

View File

@ -9,7 +9,7 @@ if ("MARKO_DEBUG") {
.enableSpecialReload(
`${extensions
.map((ext) => `*${ext}`)
.join(" ")} marko.json marko-tag.json`
.join(" ")} marko.json marko-tag.json`,
)
.onFileModified((path) => {
hotReload.handleFileModified(path);

View File

@ -9,7 +9,7 @@ exports.handleFileModified = function (filename) {
if (!fs.existsSync(filename)) {
console.log(
"[marko/hot-reload] WARNING cannot resolve template path: ",
filename
filename,
);
return;
}
@ -35,7 +35,7 @@ function tryReload(filename) {
delete require.cache[filename];
require(filename);
console.log(
`[marko] Template successfully reloaded: ${cwdRelative(filename)}`
`[marko] Template successfully reloaded: ${cwdRelative(filename)}`,
);
} catch (e) {
console.error(e);

View File

@ -14,7 +14,7 @@ const MARKO_EXTENSIONS = Symbol("MARKO_EXTENSIONS");
// eslint-disable-next-line no-constant-condition
if ("MARKO_DEBUG") {
complain(
'Using "marko/node-require" has been replaced with "@marko/compiler/register".'
'Using "marko/node-require" has been replaced with "@marko/compiler/register".',
);
}
@ -32,8 +32,8 @@ function compile(templatePath, markoCompiler, userCompilerOptions) {
{},
defaultCompilerOptions,
userCompilerOptions,
requiredCompilerOptions
)
requiredCompilerOptions,
),
).code;
}

View File

@ -4,6 +4,7 @@ const ComponentDef = require("../../../runtime/components/ComponentDef");
var FLAG_WILL_RERENDER_IN_BROWSER = 1;
// var FLAG_HAS_RENDER_BODY = 2;
var FLAG_OLD_HYDRATE_NO_CREATE = 8;
module.exports = function beginComponent(
componentsContext,
@ -11,15 +12,20 @@ module.exports = function beginComponent(
key,
ownerComponentDef,
isSplitComponent,
isImplicitComponent
isImplicitComponent,
existingComponentDef
) {
var componentId = component.id;
var componentDef = (componentsContext.___componentDef = new ComponentDef(
component,
componentId,
componentsContext
));
// existingComponentDef is only here to allow binding a conditional
// widget. It should be removed when the legacy compat layer is removed.
var componentDef =
existingComponentDef ||
(componentsContext.___componentDef = new ComponentDef(
component,
componentId,
componentsContext
));
var ownerIsRenderBoundary =
ownerComponentDef && ownerComponentDef.___renderBoundary;
@ -54,6 +60,10 @@ module.exports = function beginComponent(
componentsContext.___isPreserved = false;
}
if (out.global.oldHydrateNoCreate === true) {
componentDef.___flags |= FLAG_OLD_HYDRATE_NO_CREATE;
}
if ((ownerIsRenderBoundary || ownerWillRerender) && key != null) {
out.w(
"<!--" +

View File

@ -0,0 +1,333 @@
"use strict";
/* jshint newcap:false */
var BaseState;
var BaseComponent;
var inherit;
var req = require("@internal/require");
var registry = require("@internal/components-registry");
var jQuery = require("../../../runtime/components/legacy/jquery");
var ready = require("../../../runtime/components/legacy/ready");
var complain = "MARKO_DEBUG" && require("complain");
var stateToJSONDef = {
enumerable: false,
value: function returnSelf() {
return this;
},
};
function noop() {}
module.exports = function defineWidget(def, renderer) {
def = def.Widget || def;
if (def.___isComponent) {
return def;
}
var ComponentClass = function () {};
var proto;
var legacyInit;
if (typeof def === "function") {
proto = def.prototype;
legacyInit = def;
} else if (typeof def === "object") {
proto = def;
legacyInit = def.init;
} else {
throw TypeError();
}
ComponentClass.prototype = proto;
// We don't use the constructor provided by the user
// since we don't invoke their constructor until
// we have had a chance to do our own initialization.
// Instead, we store their constructor in the "initComponent"
// property and that method gets called later inside
// init-components-browser.js
function Component(id, doc) {
BaseComponent.call(this, id, doc);
}
if (!proto.___isComponent) {
// Inherit from Component if they didn't already
ComponentClass.prototype = Object.create(BaseComponent.prototype);
for (var propName in proto) {
if (proto.hasOwnProperty(propName)) {
ComponentClass.prototype[propName] = proto[propName];
}
}
}
// The same prototype will be used by our constructor after
// we he have set up the prototype chain using the inherit function
proto = Component.prototype = ComponentClass.prototype;
proto.___isLegacy = true;
proto.constructor = def.constructor = Component;
Object.defineProperty(proto, "state", {
get: function () {
var raw = this.___state && this.___state.___raw;
if (raw && !raw.toJSON) {
Object.defineProperty(this.___state.___raw, "toJSON", stateToJSONDef);
}
return raw;
},
set: function (newState) {
newState = newState || {};
// eslint-disable-next-line no-constant-condition
if ("MARKO_DEBUG") {
if (
Object.keys(newState).sort().join("") !==
Object.keys((this.___state && this.___state.___raw) || {})
.sort()
.join("")
)
complain(
"'widget.state = newState' has changed from merging the newState to replacing the old state."
);
}
this.setState(newState);
},
});
Object.defineProperty(proto, "__document", {
get: function () {
// eslint-disable-next-line no-constant-condition
if ("MARKO_DEBUG") {
complain("__document is deprecated");
}
return this.___host;
},
});
Object.defineProperty(proto, "el", {
get: function () {
// eslint-disable-next-line no-constant-condition
if ("MARKO_DEBUG") {
if (
this.___currentLegacyBindEl !==
(this.___rootNode && this.___rootNode.firstChild)
) {
complain(
"this.el no longer returns the `w-bind` element and instead returns the first node in the template. Assign a key to the w-bind element and use getEl(key) instead."
);
}
}
return this.___currentLegacyBindEl;
},
});
// get legacy methods
proto.___legacyOnRender = proto.onRender;
Object.defineProperty(proto, "onRender", {
get: noop,
set: function (v) {
proto.___legacyOnRender = v;
},
});
proto.___legacyOnUpdate = proto.onUpdate;
Object.defineProperty(proto, "onUpdate", {
get: function () {
return modernMountOrUpdate;
},
set: function (v) {
proto.___legacyOnUpdate = v;
},
});
proto.___legacyOnDestroy = proto.onDestroy;
Object.defineProperty(proto, "onDestroy", {
get: function () {
return modernOnDestory;
},
set: function (v) {
proto.___legacyOnDestroy = v;
},
});
proto.getWidget = proto.getComponent;
proto.getWidgets = proto.getComponents;
proto.onMount = modernMountOrUpdate;
if (legacyInit) {
proto.___legacyInit = legacyInit;
}
// convert legacy to modern
proto.___modernUpdate = proto.update;
proto.update = function () {
if (this.___destroyed) {
// eslint-disable-next-line no-constant-condition
if ("MARKO_DEBUG") {
complain(
"widget was updated after it was destroyed, if this widget is migrated to a modern component this will become a noop.",
{
location: this.___type,
}
);
}
this.destroy = modernOnDestory;
this.___destroyed = false;
}
this.___legacyExplicitUpdate = true;
if (this.___currentLegacyBindEl) {
this.onBeforeUpdate && this.onBeforeUpdate();
}
this.___modernUpdate();
this.___legacyExplicitUpdate = false;
};
function modernMountOrUpdate() {
var self = this;
var el = this.___keyedElements["@_wbind"];
var prevEl = this.___currentLegacyBindEl;
if (prevEl !== el) {
this.___currentLegacyBindEl = el;
if (prevEl) {
this.onBeforeDestroy && this.onBeforeDestroy();
this.___legacyOnDestroy && this.___legacyOnDestroy();
this.___legacyRender = undefined;
this.removeAllListeners();
}
if (el) {
this.___legacyInit && this.___legacyInit(this.widgetConfig || {});
this.___legacyOnRender && this.___legacyOnRender({ firstRender: true });
this.___legacyRender = legacyRender;
// eslint-disable-next-line no-constant-condition
if ("MARKO_DEBUG") {
Object.defineProperty(el, "__widget", {
configurable: true,
get: function () {
complain("__widget is deprecated");
return self;
},
});
} else {
el.__widget = this;
}
}
} else if (el) {
if (prevEl) {
this.___legacyOnUpdate && this.___legacyOnUpdate();
}
if (this.___didUpdate) {
this.___legacyOnRender &&
this.___legacyOnRender({ firstRender: false });
}
}
this.___widgetProps = this.___input;
this.___input = null;
this.___didUpdate = false;
}
function legacyRender() {
if (!this.___legacyExplicitUpdate) {
this.onBeforeUpdate && this.onBeforeUpdate();
}
this.___didUpdate = true;
}
function modernOnDestory() {
if (this.___currentLegacyBindEl) {
this.onBeforeDestroy && this.onBeforeDestroy();
this.___legacyOnDestroy && this.___legacyOnDestroy();
this.___currentLegacyBindEl = null;
}
}
// Set a flag on the constructor function to make it clear this is
// a component so that we can short-circuit this work later
Component.___isComponent = true;
function State() {
BaseState.apply(this, arguments);
}
inherit(State, BaseState);
proto.___State = State;
jQuery.patchComponent(
window.$,
proto,
true /* don't throw error until used if `$` is missing*/
);
ready.patchComponent(proto);
if (!renderer) {
renderer = ComponentClass.renderer || ComponentClass.prototype.renderer;
if (renderer) {
// Legacy support
var createOut = renderer.createOut;
if (typeof renderer !== "function") {
var rendererObject = renderer;
renderer = function (input, out) {
var rendererFunc = rendererObject.renderer || rendererObject.render;
rendererFunc(input, out);
};
renderer.createOut = createOut;
}
renderer.render = function (input) {
var out = createOut();
renderer(input, out);
return out.end();
};
}
}
if (renderer) {
// Add the rendering related methods as statics on the
// new component constructor function
Component.renderer = proto.___renderer = renderer;
Component.render = renderer.render;
Component.renderSync = renderer.renderSync;
}
// eslint-disable-next-line no-constant-condition
if ("MARKO_DEBUG") {
Object.defineProperty(Component, "_isWidget", {
get: function () {
complain("_isWidget is deprecated");
return true;
},
});
} else {
Component._isWidget = true;
}
var template = def.template;
if (template) {
if (typeof template === "string") {
template = req(template);
}
registry.r((template.default || template).___typeName, function () {
return Component;
});
}
return Component;
};
BaseState = require("../../../runtime/components/State");
BaseComponent = require("../../../runtime/components/Component");
inherit = require("raptor-util/inherit");

View File

@ -0,0 +1,18 @@
module.exports = function defineWidget(def, renderer) {
if (def.___isComponent) {
return def;
}
if (renderer) {
return {
___isComponent: true,
_isWidget: true,
renderer: renderer,
render: renderer.render,
renderSync: renderer.renderSync,
template: renderer.template,
};
} else {
return { ___isComponent: true, _isWidget: true };
}
};

View File

@ -0,0 +1,11 @@
{
"main": "./index.js",
"browser": "./index-browser.js",
"exports": {
".": {
"worker": "./index.js",
"browser": "./index-browser.js",
"default": "./index.js"
}
}
}

View File

@ -0,0 +1,75 @@
var Component = require("../../../runtime/components/Component");
var req = require("@internal/require");
var getComponentForEl =
require("@internal/components-util").___getComponentForEl;
var complain = "MARKO_DEBUG" && require("complain");
// expose legacy
require("@internal/components-registry").___legacy = exports;
exports.load = function (typeName) {
return exports.defineWidget(req(typeName));
};
// legacy api
exports.defineComponent = require("../../../runtime/components/legacy/defineComponent-legacy");
exports.defineWidget = require("@internal/components-define-widget-legacy");
exports.defineRenderer = require("../../../runtime/components/legacy/defineRenderer-legacy");
exports.makeRenderable =
exports.renderable = require("../../../runtime/renderable");
// browser only
var Widget = (exports.Widget = Component);
exports.getWidgetForEl = exports.get = function (elOrId) {
var el = elOrId;
if (typeof elOrId === "string") {
el = document.getElementById(elOrId);
}
if (el && el.__widget) {
return el.__widget;
}
return getComponentForEl(el);
};
exports.initWidgets =
require("@internal/components-registry").___initServerRendered;
// monkey patch Widget
if (Widget) {
var WidgetProto = Widget.prototype;
WidgetProto.setProps = function (newInput) {
this.___isReceivingNewInput = true;
this.___setInput(newInput);
};
WidgetProto.rerender = function (newInput) {
if (newInput) {
this.setProps(newInput);
}
this.forceUpdate();
this.update();
};
}
var RenderResult = require("../../../runtime/RenderResult");
RenderResult.prototype.getWidget = function () {
// eslint-disable-next-line no-constant-condition
if ("MARKO_DEBUG") {
complain("getWidget is deprecated. use getComponent instead.");
}
return this.getWidgets()[0];
};
RenderResult.prototype.getWidgets = function () {
// eslint-disable-next-line no-constant-condition
if ("MARKO_DEBUG") {
complain("getWidgets is deprecated. use getComponents instead.");
}
return RenderResult.prototype.getComponents
.apply(this, arguments)
.filter(function (component) {
return component.___isLegacy;
});
};

View File

@ -0,0 +1,16 @@
var modernMarko = require("@internal/components-entry");
// legacy api
exports.defineComponent = require("../../../runtime/components/legacy/defineComponent-legacy");
exports.defineWidget = require("@internal/components-define-widget-legacy");
exports.defineRenderer = require("../../../runtime/components/legacy/defineRenderer-legacy");
exports.makeRenderable =
exports.renderable = require("../../../runtime/renderable");
// server only
exports.writeInitWidgetsCode = modernMarko.writeInitComponentsCode;
exports.getRenderedWidgets = exports.getRenderedWidgetIds =
modernMarko.getRenderedComponents;
exports.getInitWidgetsCode = function (out) {
return modernMarko.___getInitComponentsCode(out);
};

View File

@ -0,0 +1,11 @@
{
"main": "./index.js",
"browser": "./index-browser.js",
"exports": {
".": {
"worker": "./index.js",
"browser": "./index-browser.js",
"default": "./index.js"
}
}
}

View File

@ -1,6 +1,7 @@
var registry = require("@internal/components-registry");
exports.getComponentForEl = require("@internal/components-util").___getComponentForEl;
exports.getComponentForEl =
require("@internal/components-util").___getComponentForEl;
exports.init = registry.___initServerRendered;
exports.register = function (id, component) {
registry.r(id, function () {

View File

@ -8,6 +8,8 @@ var DEFAULT_RUNTIME_ID = "M";
var FLAG_WILL_RERENDER_IN_BROWSER = 1;
var FLAG_HAS_RENDER_BODY = 2;
var FLAG_IS_LEGACY = 4;
var FLAG_OLD_HYDRATE_NO_CREATE = 8;
function safeJSONReplacer(match) {
if (match === "</") {
@ -66,56 +68,77 @@ function addComponentsFromContext(componentsContext, componentsToHydrate) {
var id = componentDef.id;
var component = componentDef.___component;
var flags = componentDef.___flags;
var isLegacy = componentDef.___isLegacy;
var state = component.state;
var input = component.input || 0;
var typeName = component.typeName;
var customEvents = component.___customEvents;
var scope = component.___scope;
var bubblingDomEvents = component.___bubblingDomEvents;
var renderBody = input.renderBody;
var state;
var needsState;
var serializedProps;
var undefinedPropNames;
var renderBody;
if (flags & FLAG_WILL_RERENDER_IN_BROWSER) {
if (typeof renderBody === "function" && renderBody.toJSON && renderBody.toJSON() === w10NOOP) {
flags |= FLAG_HAS_RENDER_BODY;
input.renderBody = undefined;
if (isLegacy) {
flags |= FLAG_IS_LEGACY;
renderBody = component.___widgetBody;
if (component.widgetConfig && isNotEmpty(component.widgetConfig)) {
serializedProps = component.widgetConfig;
}
} else {
if (component.state) {
state = component.state;
// Update state properties with an `undefined` value to have a `null`
// value so that the property name will be serialized down to the browser.
// This ensures that we add the proper getter/setter for the state property.
const stateKeys = Object.keys(state);
for (let i = stateKeys.length; i--; ) {
const stateKey = stateKeys[i];
if (state[stateKey] === undefined) {
if (undefinedPropNames) {
undefinedPropNames.push(stateKey);
} else {
undefinedPropNames = [stateKey];
}
needsState = true;
} else {
if (
!(flags & FLAG_WILL_RERENDER_IN_BROWSER) ||
flags & FLAG_OLD_HYDRATE_NO_CREATE
) {
component.___state = undefined; // We don't use `delete` to avoid V8 deoptimization
component.___input = undefined; // We don't use `delete` to avoid V8 deoptimization
component.typeName = undefined;
component.id = undefined;
component.___customEvents = undefined;
component.___scope = undefined;
component.___bubblingDomEvents = undefined;
component.___bubblingDomEventsExtraArgsCount = undefined;
component.___updatedInput = undefined;
component.___updateQueued = undefined;
needsState = true;
if (isNotEmpty(component)) {
serializedProps = component;
}
} else {
renderBody = input.renderBody;
}
}
var undefinedPropNames = undefined;
if (needsState && state) {
// Update state properties with an `undefined` value to have a `null`
// value so that the property name will be serialized down to the browser.
// This ensures that we add the proper getter/setter for the state property.
const stateKeys = Object.keys(state);
for (let i = stateKeys.length; i--; ) {
const stateKey = stateKeys[i];
if (state[stateKey] === undefined) {
if (undefinedPropNames) {
undefinedPropNames.push(stateKey);
} else {
undefinedPropNames = [stateKey];
}
}
}
}
component.___state = undefined; // We don't use `delete` to avoid V8 deoptimization
component.___input = undefined; // We don't use `delete` to avoid V8 deoptimization
component.typeName = undefined;
component.id = undefined;
component.___customEvents = undefined;
component.___scope = undefined;
component.___bubblingDomEvents = undefined;
component.___bubblingDomEventsExtraArgsCount = undefined;
component.___updatedInput = undefined;
component.___updateQueued = undefined;
if (isNotEmpty(component)) {
serializedProps = component;
}
if (typeof renderBody === "function" && renderBody.toJSON && renderBody.toJSON() === w10NOOP) {
flags |= FLAG_HAS_RENDER_BODY;
renderBody = input.renderBody = undefined;
}
var extra = {
@ -124,9 +147,10 @@ function addComponentsFromContext(componentsContext, componentsToHydrate) {
e: customEvents,
f: flags || undefined,
p: customEvents && scope, // Only serialize scope if we need to attach custom events
s: state,
s: needsState && state,
u: undefinedPropNames,
w: serializedProps
w: serializedProps,
r: renderBody,
};
var parts = [id, typeName];
@ -207,7 +231,7 @@ function getInitComponentsData(out, componentDefs) {
l: isLast && 1,
g: serializedGlobals,
w: componentDefs,
t: newTypes
t: newTypes,
};
}

View File

@ -8,6 +8,7 @@ var createFragmentNode =
var ComponentDef = require("../../../runtime/components/ComponentDef");
var domData = require("../../../runtime/components/dom-data");
var componentsUtil = require("@internal/components-util");
var req = require("@internal/require");
var componentLookup = componentsUtil.___componentLookup;
var addComponentRootToKeyedElements =
componentsUtil.___addComponentRootToKeyedElements;
@ -68,17 +69,27 @@ function addPendingDef(def, type, meta, host, runtimeId) {
def,
meta,
host,
runtimeId
runtimeId,
]);
}
function load(typeName) {
function load(typeName, isLegacy) {
var target = loaded[typeName];
if (!target) {
target = registered[typeName];
if (target) {
target = target();
} else if (isLegacy) {
target = exports.___legacy.load(typeName);
} else {
target = req(typeName);
// eslint-disable-next-line no-constant-condition
if ("MARKO_DEBUG") {
complain(
"Looks like you used `require:` in your browser.json to load a component. This requires that Marko has knowledge of how lasso generates paths and will be removed in a future version. `marko-dependencies:/path/to/template.marko` should be used instead."
);
}
}
if (!target) {
@ -91,14 +102,14 @@ function load(typeName) {
return target;
}
function getComponentClass(typeName) {
function getComponentClass(typeName, isLegacy) {
var ComponentClass = componentTypes[typeName];
if (ComponentClass) {
return ComponentClass;
}
ComponentClass = load(typeName);
ComponentClass = load(typeName, isLegacy);
ComponentClass = ComponentClass.Component || ComponentClass;
@ -124,11 +135,12 @@ function getComponentClass(typeName) {
.replace(/^[^a-z$_]/i, "_$&")
.replace(/[^0-9a-z$_]+/gi, "_");
className = className[0].toUpperCase() + className.slice(1);
// eslint-disable-next-line no-unused-vars
var OldComponentClass = ComponentClass;
ComponentClass = {
[className]: function (id, doc) {
OldComponentClass.call(this, id, doc);
}
},
}[className];
ComponentClass.prototype = OldComponentClass.prototype;
}
@ -138,8 +150,8 @@ function getComponentClass(typeName) {
return ComponentClass;
}
function createComponent(typeName, id) {
var ComponentClass = getComponentClass(typeName);
function createComponent(typeName, id, isLegacy) {
var ComponentClass = getComponentClass(typeName, isLegacy);
return new ComponentClass(id);
}
@ -290,6 +302,10 @@ function addDOMEventListeners(
function initComponent(componentDef, host) {
var component = componentDef.___component;
if (!component || !component.___isComponent) {
return; // legacy
}
component.___reset();
component.___host = host;
@ -398,7 +414,7 @@ function initServerRendered(renderedComponents, host) {
var fakeArray = (win[globalKey] = {
r: runtimeId,
concat: initServerRendered
concat: initServerRendered,
});
// eslint-disable-next-line no-constant-condition
@ -479,7 +495,9 @@ function initServerRendered(renderedComponents, host) {
.map(function (componentDef) {
var typeName = meta.___types[componentDef[1]];
return registered[typeName]
return registered[typeName] ||
document.readyState === "complete" ||
req.e(typeName)
? tryHydrateComponent(componentDef, meta, host, runtimeId)
: addPendingDef(componentDef, typeName, meta, host, runtimeId);
})
@ -567,4 +585,5 @@ exports.___createComponent = createComponent;
exports.___getComponentClass = getComponentClass;
exports.___initServerRendered = win.$initComponents = initServerRendered;
require("../../../runtime/components/ComponentsContext").___initClientRendered = initClientRendered;
require("../../../runtime/components/ComponentsContext").___initClientRendered =
initClientRendered;

View File

@ -5,6 +5,16 @@ function nextComponentIdProvider(out) {
var prefix = out.global.componentIdPrefix || out.global.widgetIdPrefix || "s"; // "s" is for server (we use "b" for the browser)
var nextId = 0;
// eslint-disable-next-line no-constant-condition
if ("MARKO_DEBUG") {
if (out.global.widgetIdPrefix) {
require("complain")(
"$global.widgetIdPrefix is deprecated. use $global.componentIdPrefix instead.",
{ location: false }
);
}
}
return function nextComponentId() {
return prefix + nextId++;
};

View File

@ -11,7 +11,7 @@ module.exports = function (data) {
},
end: function () {
writer.close();
}
},
};
var out = this.createOut(
data && data.$global,
@ -19,7 +19,7 @@ module.exports = function (data) {
undefined,
this.___shouldBuffer
);
out.once("error", err => {
out.once("error", (err) => {
facade.write = facade.end = noop;
writer.abort(err);
});

View File

@ -0,0 +1,89 @@
"use strict";
var nodePath = require("path");
var fs = require("fs");
var Module = require("module").Module;
var markoCompiler = require("../../../compiler");
var cwd = process.cwd();
var fsOptions = { encoding: "utf8" };
var requiredCompilerOptions = { modules: "cjs" };
module.exports = function load(templatePath, templateSrc, options) {
if (arguments.length === 1) {
return doLoad(templatePath);
} else if (arguments.length === 2) {
// see if second argument is templateSrc (a String)
// or options (an Object)
var lastArg = arguments[arguments.length - 1];
if (typeof lastArg === "string") {
return doLoad(templatePath, templateSrc);
} else {
var finalOptions = templateSrc;
return doLoad(templatePath, null, finalOptions);
}
} else if (arguments.length === 3) {
// assume function called according to function signature
return doLoad(templatePath, templateSrc, options);
} else {
throw new Error("Illegal arguments");
}
};
function loadSource(templatePath, compiledSrc) {
// Short-circuit loading if the template has already been cached in the Node.js require cache
var cached = require.cache[templatePath];
if (cached) {
return cached.exports;
}
var templateModule = new Module(templatePath, module);
templateModule.paths = Module._nodeModulePaths(
nodePath.dirname(templatePath)
);
templateModule.filename = templatePath;
Module._cache[templatePath] = templateModule;
templateModule._compile(compiledSrc, templatePath);
return templateModule.exports;
}
function getCachedTemplate(templatePath) {
var precompiledTemplatePath = templatePath + ".js";
var templateModule =
require.cache[templatePath] || require.cache[precompiledTemplatePath];
if (templateModule) {
return templateModule.exports;
} else if (fs.existsSync(precompiledTemplatePath)) {
return require(precompiledTemplatePath);
}
}
function doLoad(templatePath, templateSrc, options) {
options = Object.assign(
{},
markoCompiler.defaultOptions,
options,
requiredCompilerOptions
);
templatePath = nodePath.resolve(cwd, templatePath);
var template = getCachedTemplate(templatePath);
if (!template) {
if (templateSrc == null) {
templateSrc = fs.readFileSync(templatePath, fsOptions);
}
var compiledSrc = markoCompiler.compile(templateSrc, templatePath, options);
template = loadSource(templatePath, compiledSrc);
}
if (template.default) {
template = template.default;
}
return template;
}

View File

@ -1,4 +1,2 @@
"use strict";
module.exports =
// eslint-disable-next-line no-undef
typeof __webpack_require__ !== "undefined" ? __webpack_require__ : require;
module.exports = require("@internal/require");

View File

@ -1,88 +1,23 @@
"use strict";
var nodePath = require("path");
var fs = require("fs");
var Module = require("module").Module;
var markoCompiler = require("../../../compiler");
var cwd = process.cwd();
var fsOptions = { encoding: "utf8" };
var requiredCompilerOptions = { modules: "cjs" };
module.exports = function load(templatePath, templateSrc, options) {
if (arguments.length === 1) {
return doLoad(templatePath);
} else if (arguments.length === 2) {
// see if second argument is templateSrc (a String)
// or options (an Object)
var lastArg = arguments[arguments.length - 1];
if (typeof lastArg === "string") {
return doLoad(templatePath, templateSrc);
} else {
var finalOptions = templateSrc;
return doLoad(templatePath, null, finalOptions);
}
} else if (arguments.length === 3) {
// assume function called according to function signature
return doLoad(templatePath, templateSrc, options);
} else {
throw new Error("Illegal arguments");
}
};
function loadSource(templatePath, compiledSrc) {
// Short-circuit loading if the template has already been cached in the Node.js require cache
var cached = require.cache[templatePath];
if (cached) {
return cached.exports;
}
var templateModule = new Module(templatePath, module);
templateModule.paths = Module._nodeModulePaths(
nodePath.dirname(templatePath)
);
templateModule.filename = templatePath;
Module._cache[templatePath] = templateModule;
templateModule._compile(compiledSrc, templatePath);
return templateModule.exports;
}
function getCachedTemplate(templatePath) {
var precompiledTemplatePath = templatePath + ".js";
var templateModule =
require.cache[templatePath] || require.cache[precompiledTemplatePath];
if (templateModule) {
return templateModule.exports;
} else if (fs.existsSync(precompiledTemplatePath)) {
return require(precompiledTemplatePath);
}
}
function doLoad(templatePath, templateSrc, options) {
options = Object.assign(
{},
markoCompiler.defaultOptions,
options,
requiredCompilerOptions
);
templatePath = nodePath.resolve(cwd, templatePath);
var template = getCachedTemplate(templatePath);
if (!template) {
if (templateSrc == null) {
templateSrc = fs.readFileSync(templatePath, fsOptions);
}
var compiledSrc = markoCompiler.compile(templateSrc, templatePath, options);
template = loadSource(templatePath, compiledSrc);
}
if (template.default) {
template = template.default;
}
return template;
}
const req = require("@internal/require");
let fallback;
module.exports = !require.extensions[".marko"]
? require("./fallback-node")
: function load(templatePath, templateSrc, options) {
switch (arguments.length) {
case 1:
return req(templatePath);
case 2:
return (fallback = fallback || require("./fallback-node"))(
templatePath,
templateSrc
);
case 3:
return (fallback = fallback || require("./fallback-node"))(
templatePath,
templateSrc,
options
);
}
};

Some files were not shown because too many files have changed in this diff Show More