Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion e2e/qwik-nx-e2e/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"executor": "@nrwl/nx-plugin:e2e",
"options": {
"target": "qwik-nx:build",
"jestConfig": "e2e/qwik-nx-e2e/jest.config.ts"
"jestConfig": "e2e/qwik-nx-e2e/jest.config.ts",
"maxWorkers": 1
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
killPort,
} from '@qwikifiers/e2e/utils';

describe('qwik-nx e2e', () => {
describe('appGenerator e2e', () => {
// Setting up individual workspaces per
// test can cause e2e runs to take a long time.
// For this reason, we recommend each suite only
Expand All @@ -22,10 +22,10 @@ describe('qwik-nx e2e', () => {
ensureNxProject('qwik-nx', 'dist/packages/qwik-nx');
});

afterAll(() => {
afterAll(async () => {
// `nx reset` kills the daemon, and performs
// some work which can help clean up e2e leftovers
runNxCommandAsync('reset');
await runNxCommandAsync('reset');
});

describe('Basic behavior', () => {
Expand All @@ -36,6 +36,7 @@ describe('qwik-nx e2e', () => {
`generate qwik-nx:app ${project} --no-interactive`
);
}, 200000);

it('should create qwik-nx', async () => {
const result = await runNxCommandAsync(`build-ssr ${project}`);
expect(result.stdout).toContain(
Expand Down Expand Up @@ -64,5 +65,21 @@ describe('qwik-nx e2e', () => {
// ignore
}
}, 200000);

it('should serve application in preview mode with custom port', async () => {
const port = 4232;
const p = await runCommandUntil(
`run ${project}:preview --port=${port}`,
(output) => {
return output.includes('Local:') && output.includes(`:${port}`);
}
);
try {
await promisifiedTreeKill(p.pid, 'SIGKILL');
await killPort(port);
} catch {
// ignore
}
}, 200000);
});
});
137 changes: 137 additions & 0 deletions e2e/qwik-nx-e2e/tests/qwik-nx-vite.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import {
checkFilesExist,
ensureNxProject,
readFile,
renameFile,
runNxCommandAsync,
uniq,
updateFile,
} from '@nrwl/nx-plugin/testing';

import {
runCommandUntil,
promisifiedTreeKill,
killPort,
removeFile,
} from '@qwikifiers/e2e/utils';

describe('qwikNxVite plugin e2e', () => {
// Setting up individual workspaces per
// test can cause e2e runs to take a long time.
// For this reason, we recommend each suite only
// consumes 1 workspace. The tests should each operate
// on a unique project in the workspace, such that they
// are not dependant on one another.
beforeAll(() => {
ensureNxProject('qwik-nx', 'dist/packages/qwik-nx');
});

afterAll(async () => {
// `nx reset` kills the daemon, and performs
// some work which can help clean up e2e leftovers
await runNxCommandAsync('reset');
});

describe('should be able to import components from libraries', () => {
let project: string;
let headerLibName: string;
let iconLibName: string;
beforeAll(async () => {
project = uniq('qwik-nx');
headerLibName = uniq('qwik-nx-header');
iconLibName = uniq('qwik-nx-icon');
await runNxCommandAsync(
`generate qwik-nx:app ${project} --no-interactive`
);
await runNxCommandAsync(
`generate qwik-nx:library ${headerLibName} --unitTestRunner=none --no-interactive`
);
await runNxCommandAsync(
`generate qwik-nx:library ${iconLibName} --unitTestRunner=none --no-interactive`
);

// move header component into the library

// update import in layout.tsx
const layoutFilePath = `apps/${project}/src/routes/layout.tsx`;
let layoutFile = readFile(layoutFilePath);
layoutFile = layoutFile.replace(
`import Header from '../components/header/header';`,
`import { Header } from '@proj/${headerLibName}';`
);
updateFile(layoutFilePath, layoutFile);

// move header component files
const headerFolderOldPath = `apps/${project}/src/components/header`;
const headerFolderNewPath = `libs/${headerLibName}/src/lib`;
removeFile(`${headerFolderNewPath}/${headerLibName}.tsx`);
removeFile(`${headerFolderNewPath}/${headerLibName}.css`);
renameFile(
`${headerFolderOldPath}/header.tsx`,
`${headerFolderNewPath}/header.tsx`
);
renameFile(
`${headerFolderOldPath}/header.css`,
`${headerFolderNewPath}/header.css`
);
updateFile(
`libs/${headerLibName}/src/index.ts`,
`export * from './lib/header';`
);

// update header.tsx contents
let headerTsx = readFile(`${headerFolderNewPath}/header.tsx`);
headerTsx = headerTsx.replace(
`import { QwikLogo } from '../icons/qwik';`,
`import { QwikLogo } from '@proj/${iconLibName}';`
);
headerTsx = headerTsx.replace(
'export default component$(() => {',
'export const Header = component$(() => {'
);
updateFile(`${headerFolderNewPath}/header.tsx`, headerTsx);

// move icon component file
const qwikIconFolderNewPath = `libs/${iconLibName}/src/lib`;
removeFile(`${qwikIconFolderNewPath}/${iconLibName}.tsx`);
removeFile(`${qwikIconFolderNewPath}/${iconLibName}.css`);
renameFile(
`apps/${project}/src/components/icons/qwik.tsx`,
`${qwikIconFolderNewPath}/qwik.tsx`
);
updateFile(
`libs/${iconLibName}/src/index.ts`,
`export * from './lib/qwik';`
);
}, 200000);

it('should be able to successfully build the application', async () => {
const result = await runNxCommandAsync(`build-ssr ${project}`);
expect(result.stdout).toContain(
`Successfully ran target build-ssr for project ${project}`
);
expect(() =>
checkFilesExist(`dist/apps/${project}/client/q-manifest.json`)
).not.toThrow();
expect(() =>
checkFilesExist(`dist/apps/${project}/server/entry.preview.mjs`)
).not.toThrow();
}, 200000);

it('should serve application in preview mode with custom port', async () => {
const port = 4212;
const p = await runCommandUntil(
`run ${project}:preview --port=${port}`,
(output) => {
return output.includes('Local:') && output.includes(`:${port}`);
}
);
try {
await promisifiedTreeKill(p.pid, 'SIGKILL');
await killPort(port);
} catch {
// ignore
}
}, 200000);
});
});
43 changes: 3 additions & 40 deletions e2e/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ export const promisifiedTreeKill: (
) => Promise<void> = promisify(treeKill);

export function getNxVersion(): string {
const version = readJsonFile(
const { dependencies } = readJsonFile(
join(workspaceRoot, `./dist/packages/qwik-nx/package.json`)
).peerDependencies.nx;
);
const version = dependencies['@nrwl/vite'];
if (!version) {
throw new Error('Could not retrieve Nx version');
}
Expand Down Expand Up @@ -217,44 +218,6 @@ export function expectTestsPass(v: { stdout: string; stderr: string }) {
expect(v.stderr).not.toContain('fail');
}

export function createFile(f: string, content: string = ''): void {
const path = tmpProjPath(f);
createFileSync(path);
if (content) {
updateFile(f, content);
}
}

export function updateFile(
f: string,
content: string | ((content: string) => string)
): void {
ensureDirSync(path.dirname(tmpProjPath(f)));
if (typeof content === 'string') {
writeFileSync(tmpProjPath(f), content);
} else {
writeFileSync(
tmpProjPath(f),
content(readFileSync(tmpProjPath(f)).toString())
);
}
}

export function renameFile(f: string, newPath: string): void {
ensureDirSync(path.dirname(tmpProjPath(newPath)));
renameSync(tmpProjPath(f), tmpProjPath(newPath));
}

export function updateJson<T extends object = any, U extends object = T>(
f: string,
updater: (value: T) => U
) {
updateFile(f, (s) => {
const json = JSON.parse(s);
return JSON.stringify(updater(json), null, 2);
});
}

export function checkFilesDoNotExist(...expectedFiles: string[]) {
expectedFiles.forEach((f) => {
const ff = f.startsWith('/') ? f : tmpProjPath(f);
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
},
"private": true,
"devDependencies": {
"@builder.io/qwik": "0.17.4",
"@commitlint/cli": "^17.3.0",
"@commitlint/config-angular": "^17.3.0",
"@commitlint/config-conventional": "^17.3.0",
Expand Down Expand Up @@ -55,7 +56,8 @@
"tree-kill": "1.2.2",
"ts-jest": "28.0.5",
"ts-node": "10.9.1",
"typescript": "~4.8.2"
"typescript": "~4.8.2",
"vite": "4.1.1"
},
"dependencies": {
"@swc/helpers": "~0.4.11",
Expand Down
1 change: 1 addition & 0 deletions packages/qwik-nx/generators.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './src/generators';
2 changes: 2 additions & 0 deletions packages/qwik-nx/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// This is explicitly empty, but serves as a primary compilation entry-point.
export default {};
7 changes: 6 additions & 1 deletion packages/qwik-nx/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"name": "qwik-nx",
"version": "0.8.0",
"main": "src/index.js",
"main": "./index.js",
"typings": "./index.d.ts",
"license": "MIT",
"author": "Shai Reznik",
"description": "Nx plugin for qwik",
Expand All @@ -22,5 +23,9 @@
"executors": "./executors.json",
"dependencies": {
"@nrwl/vite": "~15.6.0"
},
"peerDependencies": {
"@builder.io/qwik": "^0.16.0",
"vite": "~4.1.1"
}
}
1 change: 1 addition & 0 deletions packages/qwik-nx/plugins.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './src/plugins';
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import { qwikVite } from '@builder.io/qwik/optimizer';
import { qwikCity } from '@builder.io/qwik-city/vite';
import { defineConfig } from 'vite';
import tsconfigPaths from 'vite-tsconfig-paths';
import { qwikNxVite } from 'qwik-nx/plugins';

export default defineConfig({
plugins: [
qwikNxVite(),
qwikCity(),
qwikVite({
client: {
Expand All @@ -14,7 +16,7 @@ export default defineConfig({
outDir: '<%= offsetFromRoot %>dist/<%= projectRoot %>/server',
},
}),
tsconfigPaths()
tsconfigPaths({ root: '<%= offsetFromRoot %>' })
],
server: {
fs: {
Expand Down
4 changes: 3 additions & 1 deletion packages/qwik-nx/src/generators/component/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ function createComponentFiles(tree: Tree, options: NormalizedSchema) {
}
}

export default async function componentGenerator(
export async function componentGenerator(
tree: Tree,
options: ComponentGeneratorSchema
) {
Expand All @@ -105,3 +105,5 @@ export default async function componentGenerator(

return addStyledModuleDependencies(tree, normalizedOptions.style);
}

export default componentGenerator;
16 changes: 16 additions & 0 deletions packages/qwik-nx/src/generators/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export { appGenerator } from './application/generator';
export { QwikAppGeneratorSchema } from './application/schema';
export { componentGenerator } from './component/generator';
export { ComponentGeneratorSchema } from './component/schema';
export { addE2eProject } from './e2e-project/generator';
export { E2eProjectGeneratorSchema } from './e2e-project/schema';
export { qwikInitGenerator } from './init/init';
export { InitGeneratorSchema } from './init/schema';
export { cloudflarePagesIntegrationGenerator } from './integrations/cloudflare-pages-integration/generator';
export { CloudflarePagesIntegrationGeneratorSchema } from './integrations/cloudflare-pages-integration/schema';
export { libraryGenerator } from './library/generator';
export { LibraryGeneratorSchema } from './library/schema';
export { routeGenerator } from './route/generator';
export { RouteGeneratorSchema } from './route/schema';
export { setupTailwindGenerator } from './setup-tailwind/setup-tailwind';
export { SetupTailwindOptions } from './setup-tailwind/schema';
4 changes: 3 additions & 1 deletion packages/qwik-nx/src/generators/init/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ function updateDependencies(host: Tree) {
);
}

export default async function qwikInitGenerator(
export async function qwikInitGenerator(
tree: Tree,
options: InitGeneratorSchema
) {
Expand All @@ -48,3 +48,5 @@ export default async function qwikInitGenerator(
}
return runTasksInSerial(installTask);
}

export default qwikInitGenerator;
Loading