-
Notifications
You must be signed in to change notification settings - Fork 142
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1550 from embroider-build/vite-app
Initial test of vite integration
- Loading branch information
Showing
60 changed files
with
3,683 additions
and
1,209 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
<h2 id="title">Welcome to Ember</h2> | ||
|
||
{{@model.message}} | ||
|
||
{{outlet}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# compiled output | ||
/src/**/*.js | ||
/src/**/*.d.ts | ||
|
||
# shims | ||
/index.d.ts | ||
/index.mjs | ||
|
||
# dependencies | ||
/node_modules/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
/node_modules | ||
/src/**/*.js | ||
/src/**/*.d.ts | ||
/src/**/*.map | ||
/*/tests/**/*.js | ||
/*/tests/**/*.d.ts | ||
/*/tests/**/*.map |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export * from './src/resolver.js'; | ||
export * from './src/hbs.js'; | ||
export * from './src/scripts.js'; | ||
export * from './src/template-tag.js'; | ||
export * from './src/addons.js'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export * from './src/resolver.js'; | ||
export * from './src/hbs.js'; | ||
export * from './src/scripts.js'; | ||
export * from './src/template-tag.js'; | ||
export * from './src/addons.js'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{ | ||
"name": "@embroider/vite", | ||
"version": "0.0.0", | ||
"main": "index.mjs", | ||
"peerDependencies": { | ||
"@embroider/core": "workspace:^", | ||
"vite": "^4.3.9" | ||
}, | ||
"dependencies": { | ||
"@rollup/pluginutils": "^4.1.1", | ||
"assert-never": "^1.2.1", | ||
"content-tag": "^1.0.0", | ||
"debug": "^4.3.2", | ||
"fs-extra": "^10.0.0", | ||
"jsdom": "^16.6.0", | ||
"source-map-url": "^0.4.1", | ||
"terser": "^5.7.0" | ||
}, | ||
"devDependencies": { | ||
"@embroider/core": "workspace:^", | ||
"@types/debug": "^4.1.5", | ||
"@types/jsdom": "^16.2.11", | ||
"@types/fs-extra": "^9.0.12", | ||
"rollup": "^3.23.0", | ||
"vite": "^4.3.9" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { ResolverLoader, packageName } from '@embroider/core'; | ||
|
||
export function addons(root: string): string[] { | ||
let rloader = new ResolverLoader(root); | ||
let { options } = rloader.resolver; | ||
let names = new Set<string>(); | ||
for (let from of Object.keys(options.renameModules)) { | ||
let pName = packageName(from); | ||
if (pName) { | ||
names.add(pName); | ||
} | ||
} | ||
for (let from of Object.keys(options.renamePackages)) { | ||
names.add(from); | ||
} | ||
for (let name of Object.keys(options.activeAddons)) { | ||
names.add(name); | ||
} | ||
return [...names]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
// TODO: I copied this from @embroider/addon-dev, it needs to be its own package | ||
// (or be in shared-internals or core) | ||
import { createFilter } from '@rollup/pluginutils'; | ||
import type { PluginContext, ResolvedId } from 'rollup'; | ||
import type { Plugin } from 'vite'; | ||
import { readFileSync } from 'fs'; | ||
import { hbsToJS } from '@embroider/core'; | ||
import assertNever from 'assert-never'; | ||
import { parse as pathParse } from 'path'; | ||
import makeDebug from 'debug'; | ||
|
||
const debug = makeDebug('embroider:hbs-plugin'); | ||
|
||
export function hbs(): Plugin { | ||
return { | ||
name: 'rollup-hbs-plugin', | ||
enforce: 'pre', | ||
async resolveId(source: string, importer: string | undefined) { | ||
let resolution = await this.resolve(source, importer, { | ||
skipSelf: true, | ||
}); | ||
|
||
if (!resolution) { | ||
return maybeSynthesizeComponentJS(this, source, importer); | ||
} else { | ||
return maybeRewriteHBS(resolution); | ||
} | ||
}, | ||
|
||
load(id: string) { | ||
const meta = getMeta(this, id); | ||
if (!meta) { | ||
return; | ||
} | ||
|
||
switch (meta.type) { | ||
case 'template': | ||
let input = readFileSync(id, 'utf8'); | ||
let code = hbsToJS(input); | ||
return { | ||
code, | ||
}; | ||
case 'template-only-component-js': | ||
return { | ||
code: templateOnlyComponent, | ||
}; | ||
default: | ||
assertNever(meta); | ||
} | ||
}, | ||
}; | ||
} | ||
|
||
const templateOnlyComponent = | ||
`import templateOnly from '@ember/component/template-only';\n` + `export default templateOnly();\n`; | ||
|
||
type Meta = | ||
| { | ||
type: 'template'; | ||
} | ||
| { | ||
type: 'template-only-component-js'; | ||
}; | ||
|
||
function getMeta(context: PluginContext, id: string): Meta | null { | ||
const meta = context.getModuleInfo(id)?.meta?.['rollup-hbs-plugin']; | ||
if (meta) { | ||
return meta as Meta; | ||
} else { | ||
return null; | ||
} | ||
} | ||
|
||
function correspondingTemplate(filename: string): string { | ||
let { ext } = pathParse(filename); | ||
return filename.slice(0, filename.length - ext.length) + '.hbs'; | ||
} | ||
|
||
async function maybeSynthesizeComponentJS(context: PluginContext, source: string, importer: string | undefined) { | ||
debug(`checking for template-only component: %s`, source); | ||
let templateResolution = await context.resolve(correspondingTemplate(source), importer, { | ||
skipSelf: true, | ||
custom: { | ||
embroider: { | ||
// we don't want to recurse into the whole embroider compatbility | ||
// resolver here. It has presumably already steered our request to the | ||
// correct place. All we want to do is slightly modify the request we | ||
// were given (changing the extension) and check if that would resolve | ||
// instead. | ||
// | ||
// Currently this guard is only actually exercised in rollup, not in | ||
// vite, due to https://github.com/vitejs/vite/issues/13852 | ||
enableCustomResolver: false, | ||
}, | ||
}, | ||
}); | ||
if (!templateResolution) { | ||
return null; | ||
} | ||
debug(`emitting template only component: %s`, templateResolution.id); | ||
|
||
// we're trying to resolve a JS module but only the corresponding HBS | ||
// file exists. Synthesize the template-only component JS. | ||
return { | ||
id: templateResolution.id.replace(/\.hbs$/, '.js'), | ||
meta: { | ||
'rollup-hbs-plugin': { | ||
type: 'template-only-component-js', | ||
}, | ||
}, | ||
}; | ||
} | ||
|
||
const hbsFilter = createFilter('**/*.hbs'); | ||
|
||
function maybeRewriteHBS(resolution: ResolvedId) { | ||
if (!hbsFilter(resolution.id)) { | ||
return null; | ||
} | ||
debug('emitting hbs rewrite: %s', resolution.id); | ||
return { | ||
...resolution, | ||
meta: { | ||
'rollup-hbs-plugin': { | ||
type: 'template', | ||
}, | ||
}, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { ModuleRequest, cleanUrl } from '@embroider/core'; | ||
|
||
export const virtualPrefix = 'embroider_virtual:'; | ||
|
||
export class RollupModuleRequest implements ModuleRequest { | ||
static from( | ||
source: string, | ||
importer: string | undefined, | ||
custom: Record<string, any> | undefined | ||
): RollupModuleRequest | undefined { | ||
if (!(custom?.embroider?.enableCustomResolver ?? true)) { | ||
return; | ||
} | ||
|
||
if (source && importer && source[0] !== '\0') { | ||
let nonVirtual: string; | ||
if (importer.startsWith(virtualPrefix)) { | ||
nonVirtual = importer.slice(virtualPrefix.length); | ||
} else { | ||
nonVirtual = importer; | ||
} | ||
|
||
// strip query params off the importer | ||
let fromFile = cleanUrl(nonVirtual); | ||
return new RollupModuleRequest(source, fromFile, custom?.embroider?.meta); | ||
} | ||
} | ||
|
||
private constructor( | ||
readonly specifier: string, | ||
readonly fromFile: string, | ||
readonly meta: Record<string, any> | undefined | ||
) {} | ||
|
||
get isVirtual(): boolean { | ||
return this.specifier.startsWith(virtualPrefix); | ||
} | ||
|
||
alias(newSpecifier: string) { | ||
return new RollupModuleRequest(newSpecifier, this.fromFile, this.meta) as this; | ||
} | ||
rehome(newFromFile: string) { | ||
if (this.fromFile === newFromFile) { | ||
return this; | ||
} else { | ||
return new RollupModuleRequest(this.specifier, newFromFile, this.meta) as this; | ||
} | ||
} | ||
virtualize(filename: string) { | ||
return new RollupModuleRequest(virtualPrefix + filename, this.fromFile, this.meta) as this; | ||
} | ||
withMeta(meta: Record<string, any> | undefined): this { | ||
return new RollupModuleRequest(this.specifier, this.fromFile, meta) as this; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import type { PluginContext, ResolveIdResult } from 'rollup'; | ||
import { Plugin } from 'vite'; | ||
import { join } from 'path'; | ||
import { | ||
Resolution, | ||
Resolver, | ||
ResolverFunction, | ||
ResolverOptions, | ||
locateEmbroiderWorkingDir, | ||
virtualContent, | ||
} from '@embroider/core'; | ||
import { readJSONSync } from 'fs-extra'; | ||
import { RollupModuleRequest, virtualPrefix } from './request'; | ||
import assertNever from 'assert-never'; | ||
|
||
export function resolver(): Plugin { | ||
let resolverOptions: ResolverOptions = readJSONSync(join(locateEmbroiderWorkingDir(process.cwd()), 'resolver.json')); | ||
let resolver = new Resolver(resolverOptions); | ||
|
||
return { | ||
name: 'embroider-resolver', | ||
enforce: 'pre', | ||
async resolveId(source, importer, options) { | ||
let request = RollupModuleRequest.from(source, importer, options.custom); | ||
if (!request) { | ||
// fallthrough to other rollup plugins | ||
return null; | ||
} | ||
let resolution = await resolver.resolve(request, defaultResolve(this)); | ||
switch (resolution.type) { | ||
case 'found': | ||
return resolution.result; | ||
case 'not_found': | ||
return null; | ||
default: | ||
throw assertNever(resolution); | ||
} | ||
}, | ||
load(id) { | ||
if (id.startsWith(virtualPrefix)) { | ||
return virtualContent(id.slice(virtualPrefix.length), resolver); | ||
} | ||
}, | ||
}; | ||
} | ||
|
||
function defaultResolve(context: PluginContext): ResolverFunction<RollupModuleRequest, Resolution<ResolveIdResult>> { | ||
return async (request: RollupModuleRequest) => { | ||
if (request.isVirtual) { | ||
return { | ||
type: 'found', | ||
result: { id: request.specifier, resolvedBy: request.fromFile }, | ||
}; | ||
} | ||
let result = await context.resolve(request.specifier, request.fromFile, { | ||
skipSelf: true, | ||
custom: { | ||
embroider: { | ||
meta: request.meta, | ||
}, | ||
}, | ||
}); | ||
if (result) { | ||
return { type: 'found', result }; | ||
} else { | ||
return { type: 'not_found', err: undefined }; | ||
} | ||
}; | ||
} |
Oops, something went wrong.