Skip to content

Commit

Permalink
css imports and raw plugin interop with test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
thescientist13 committed Apr 20, 2024
1 parent 292ddfb commit 56a7657
Show file tree
Hide file tree
Showing 26 changed files with 228 additions and 33 deletions.
9 changes: 6 additions & 3 deletions packages/cli/src/config/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ function greenwoodResourceLoader (compilation) {
// : 'empty'
const headers = {
// 'Content-Type': type === 'css' ? 'text/css' : 'text/javascript',
'Accept': 'text/javascript',
'Sec-Fetch-Dest': 'empty'
};

Expand Down Expand Up @@ -194,6 +195,7 @@ function greenwoodImportMetaUrl(compilation) {
// : 'empty'
const headers = {
// 'Content-Type': type === 'css' ? 'text/css' : 'text/javascript',
'Accept': 'text/javascript',
'Sec-Fetch-Dest': 'empty'
};
const request = new Request(idUrl, {
Expand Down Expand Up @@ -370,9 +372,10 @@ const getRollupConfigForScriptResources = async (compilation) => {
chunkFileNames: '[name].[hash].js',
sourcemap: true
},
acornInjectPlugins: [
importAttributes
],
// TODO do we need this?
// acornInjectPlugins: [
// importAttributes
// ],
plugins: [
greenwoodResourceLoader(compilation),
greenwoodSyncPageResourceBundlesPlugin(compilation),
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/lifecycles/bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ async function bundleStyleResources(compilation, resourcePlugins) {
} else {
const url = resource.sourcePathURL;
const contentType = 'text/css';
const headers = new Headers({ 'Content-Type': contentType });
const headers = new Headers({ 'Content-Type': contentType, 'Accept': contentType });
const request = new Request(url, { headers });
const initResponse = new Response(contents, { headers });

Expand Down
14 changes: 5 additions & 9 deletions packages/cli/src/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@ const resourcePlugins = config.plugins.filter(plugin => plugin.type === 'resourc
}));

async function getCustomLoaderResponse(url, type = '', checkOnly = false) {
// const dest = type === 'css'
// ? 'style'
// : 'empty'
const headers = {
// 'Content-Type': type === 'css' ? 'text/css' : 'text/javascript',
'Accept': 'text/javascript',
'Sec-Fetch-Dest': 'empty'
};
const request = new Request(url, { headers });
Expand Down Expand Up @@ -64,8 +62,7 @@ async function getCustomLoaderResponse(url, type = '', checkOnly = false) {
// https://nodejs.org/docs/latest-v18.x/api/esm.html#resolvespecifier-context-nextresolve
export async function resolve(specifier, context, defaultResolve) {
const { parentURL } = context;
// const fauxType = specifier.indexOf('?type=raw') > 0 ? 'raw' : false;
const type = context?.importAttributes?.type || undefined;
const type = context?.importAttributes?.type;
const url = specifier.startsWith('file://')
? new URL(specifier)
: specifier.startsWith('.')
Expand All @@ -89,18 +86,17 @@ export async function resolve(specifier, context, defaultResolve) {
// https://nodejs.org/docs/latest-v18.x/api/esm.html#loadurl-context-nextload
export async function load(source, context, defaultLoad) {
const extension = source.split('.').pop();
// const fauxType = source.indexOf('?type=raw') > 0 ? 'raw' : false; // TODO
const type = context?.importAttributes?.type || undefined;
const type = context?.importAttributes?.type;
const url = new URL(source);
const { shouldHandle } = await getCustomLoaderResponse(url, type, true);

if (shouldHandle && extension !== 'js') {
const { response } = await getCustomLoaderResponse(url, type);
const body = await response.text();
const contents = await response.text();

return {
format: 'module',
source: body,
source: contents,
shortCircuit: true
};
}
Expand Down
6 changes: 3 additions & 3 deletions packages/cli/src/plugins/resource/plugin-standard-css.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,10 @@ class StandardCssResource extends ResourceInterface {

async shouldIntercept(url, request) {
const { pathname, searchParams } = url;
const type = pathname.split('.').pop();
const dest = request.headers.get('Sec-Fetch-Dest');
const ext = pathname.split('.').pop();
// const dest = request.headers.get('Sec-Fetch-Dest');

return url.protocol === 'file:' && type === this.extensions[0] && dest === 'empty' && searchParams.has('type') !== true;
return url.protocol === 'file:' && ext === this.extensions[0] && request.headers.get('Accept')?.indexOf('text/javascript') >= 0 && !searchParams.has('type') // dest === 'empty' && searchParams.has('type') !== true;
}

async intercept(url, request, response) {
Expand Down
8 changes: 4 additions & 4 deletions packages/cli/src/plugins/resource/plugin-standard-json.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ class StandardJsonResource extends ResourceInterface {
}

async shouldIntercept(url, request) {
const { protocol, pathname } = url;
const type = pathname.split('.').pop();
const dest = request.headers.get('sec-fetch-dest');
const { protocol, pathname, searchParams } = url;
const ext = pathname.split('.').pop();
// const dest = request.headers.get('sec-fetch-dest');

return protocol === 'file:' && dest === 'empty' && type === this.extensions[0];
return protocol === 'file:' && request.headers.get('Accept')?.indexOf('text/javascript') >= 0 && ext === this.extensions[0] && !searchParams.has('type'); // dest === 'empty' && type === this.extensions[0];
}

async intercept(url, request, response) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Use Case
* Run Greenwood serve command with no config for using import attributes with a basic static bundles.
*
* User Result
* Should start the development server and render a bare bones Greenwood build.
*
* User Command
* greenwood serve
*
* User Config
* {}
*
* User Workspace
* src/
* components/
* card/
* card.css
* card.js
* card.json
* pages/
* index.html
*
*/
import chai from 'chai';
import fs from 'fs';
import glob from 'glob-promise';
import path from 'path';
import { Runner } from 'gallinago';
import { fileURLToPath, URL } from 'url';

const expect = chai.expect;

describe('Build Greenwood With: ', function() {
const LABEL = 'Import Attributes used in static pages';
const cliPath = path.join(process.cwd(), 'packages/cli/src/index.js');
const outputPath = fileURLToPath(new URL('.', import.meta.url));
const hostname = 'http://localhost:8080';
let runner;

before(function() {
this.context = {
hostname
};
runner = new Runner(false, true);
});

describe(LABEL, function() {

before(async function() {
runner.setup(outputPath);
runner.runCommand(cliPath, 'build');
});

describe('Importing CSS w/ Constructable Stylesheets', function() {
let scripts;

before(async function() {
scripts = await glob.promise(path.join(outputPath, 'public/card.*.js'));
});

it('should have the expected output from importing hero.css as a Constructable Stylesheet', function() {
const scriptContents = fs.readFileSync(scripts[0], 'utf-8');

expect(scriptContents).to.contain('const e=new CSSStyleSheet;e.replaceSync(":host { color: red; }");');
});
});
});

after(function() {
runner.stopCommand();
runner.teardown([
path.join(outputPath, '.greenwood'),
path.join(outputPath, 'node_modules')
]);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<script type="module" src="../components/card/card.js"></script>
</head>

<body>
<h1>The home page</h1>
<app-card></app-card>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@
*
* {
* prerender: true,
* plugins: [{
* greenwoodPluginImportCss()
* }]
* }
*
* User Workspace
Expand Down Expand Up @@ -67,10 +64,12 @@ describe('(Experimental) Build Greenwood With: ', function() {
scripts = await glob.promise(path.join(this.context.publicDir, '*.js'));
});

// TODO is this actually the output we want here?
// https://github.com/ProjectEvergreen/greenwood/discussions/1216
it('should have the expected output from importing hero.css as a Constructable Stylesheet', function() {
const scriptContents = fs.readFileSync(scripts[0], 'utf-8');

expect(scriptContents).to.contain('const e=new CSSStyleSheet;e.replaceSync(":host { text-align: center');
expect(scriptContents).to.contain('const t=new CSSStyleSheet;t.replaceSync(":host { text-align: center');
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ export default class HeroBanner extends HTMLElement {
}

connectedCallback() {
console.log({ sheet, data });

if (!this.shadowRoot) {
const template = document.createElement('template');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@
* card.json
* pages/
* greeting.js
*
* package.json
*
*/
import chai from 'chai';
import { JSDOM } from 'jsdom';
Expand Down Expand Up @@ -61,6 +60,56 @@ describe('Develop Greenwood With: ', function() {
});
});

describe('CSS file is returned as CSS (text/css)', function() {
let response = {};
let body;

before(async function() {
response = await fetch(`${hostname}/components/card/card.css`);
body = await response.clone().text();
});

it('should return a 200 status', function(done) {
expect(response.status).to.equal(200);
done();
});

it('should return the correct content type', function(done) {
expect(response.headers.get('content-type')).to.equal('text/css');
done();
});

it('should return the correct response body', function(done) {
expect(body).to.equal(':host {\n color: red;\n}');
done();
});
});

describe('JSON file is returned as JSON (application/json)', function() {
let response = {};
let data;

before(async function() {
response = await fetch(`${hostname}/components/card/card.json`);
data = await response.clone().json();
});

it('should return a 200 status', function(done) {
expect(response.status).to.equal(200);
done();
});

it('should return the correct content type', function(done) {
expect(response.headers.get('content-type')).to.equal('application/json');
done();
});

it('should return the correct response body data', function(done) {
expect(data.image.url).to.equal('/path/to/image.webp');
done();
});
});

describe('API Route specific behaviors for an HTML ("fragment") API', function() {
const name = 'Greenwood';
let response = {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@
* card.json
* pages/
* greeting.js
*
* package.json
*
*/
import chai from 'chai';
import fs from 'fs';
import glob from 'glob-promise';
import { JSDOM } from 'jsdom';
import path from 'path';
import { Runner } from 'gallinago';
Expand Down Expand Up @@ -66,10 +67,12 @@ describe('Serve Greenwood With: ', function() {
const name = 'Greenwood';
let response = {};
let body;
let scripts;

before(async function() {
response = await fetch(`${hostname}/api/fragment?name=${name}`);
body = await response.clone().text();
scripts = await glob.promise(path.join(outputPath, 'public/api/card.*.js'));
});

it('should return a 200 status', function(done) {
Expand All @@ -93,15 +96,29 @@ describe('Serve Greenwood With: ', function() {

done();
});

it('should have the expected output from importing hero.css as a Constructable Stylesheet', function() {
const scriptContents = fs.readFileSync(scripts[0], 'utf-8');

expect(scriptContents).to.contain('const sheet = new CSSStyleSheet();sheet.replaceSync(`:host { color: red; }`);');
});

it('should have the expected output from importing hero.json', function() {
const scriptContents = fs.readFileSync(scripts[0], 'utf-8');

expect(scriptContents).to.contain('var data = {"image":{"url":"/path/to/image.webp"}};');
});
});

describe('SSR route specific behaviors when using a custom element as the page', function() {
let response = {};
let body;
let scripts;

before(async function() {
response = await fetch(`${hostname}/greeting/`);
body = await response.clone().text();
scripts = await glob.promise(path.join(outputPath, 'public/greeting.route.chunk.*.js'));
});

it('should return a 200 status', function(done) {
Expand All @@ -125,6 +142,18 @@ describe('Serve Greenwood With: ', function() {

done();
});

it('should have the expected output from importing hero.css as a Constructable Stylesheet', function() {
const scriptContents = fs.readFileSync(scripts[0], 'utf-8');

expect(scriptContents).to.contain('const sheet = new CSSStyleSheet();sheet.replaceSync(`:host { color: red; }`);');
});

it('should have the expected output from importing hero.json', function() {
const scriptContents = fs.readFileSync(scripts[0], 'utf-8');

expect(scriptContents).to.contain('var data = {"image":{"url":"/path/to/image.webp"}};');
});
});
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:host {
color: red;
}
Loading

0 comments on commit 56a7657

Please sign in to comment.