Skip to content
This repository has been archived by the owner on Nov 17, 2022. It is now read-only.

Commit

Permalink
Feat: define routes and ignore route files (#69)
Browse files Browse the repository at this point in the history
* feat: support define routes

* fix: test

* fix: test

* chore: undefined type

* fix: conflict

* chore: remove pages str from route id

* fix: watch route change

* fix: warn

* fix: test

* fix: test

* chore: example

* chore: add route-gen example

* feat: add integration test

* chore: test

* chore: update config file

* chore: remove pnpm cache

* chore: test

* chore: remove test:ci from ci workflow

* chore: update build-scripts version

* chore: build fixture

* chore: remove devServer test

* chore: buildFixture

* feat: add vitest

* chore: add ts-ignore

* chore: node ci version

* chore: comment bundle analyzer

* chore: add test timeout

* fix: lint

* chore: remove threads

* chore: set maxThreads and minThreads

* chore: add maxConcurrency

* chore: remove coverage

* chore: threads

* chore: set threads to false

* fix: conflict

* fix: comment
  • Loading branch information
luhc228 authored Apr 14, 2022
1 parent 95d49c4 commit d19f21e
Show file tree
Hide file tree
Showing 40 changed files with 1,011 additions and 775 deletions.
14 changes: 14 additions & 0 deletions examples/routes-generate/ice.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { defineConfig } from '@ice/app';

export default defineConfig({
routes: {
ignoreFiles: ['about.tsx', 'products.tsx'],
defineRoutes: (route) => {
route('/about-me', 'about.tsx');

route('/', 'layout.tsx', () => {
route('/product', 'products.tsx');
});
},
},
});
23 changes: 23 additions & 0 deletions examples/routes-generate/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "basic-project",
"version": "1.0.0",
"scripts": {
"start": "ice start",
"build": "ice build"
},
"description": "",
"author": "",
"license": "MIT",
"dependencies": {
"@ice/app": "file:../../packages/ice",
"@ice/runtime": "^1.0.0",
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"@types/react": "^17.0.39",
"@types/react-dom": "^17.0.11",
"browserslist": "^4.19.3",
"regenerator-runtime": "^0.13.9"
}
}
3 changes: 3 additions & 0 deletions examples/routes-generate/src/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { defineAppConfig } from 'ice';

export default defineAppConfig({});
26 changes: 26 additions & 0 deletions examples/routes-generate/src/document.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* eslint-disable react/self-closing-comp */
import React from 'react';
import { Meta, Title, Links, Main, Scripts } from 'ice';

function Document(props) {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="description" content="ICE 3.0 Demo" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Title />
<Links />
</head>
<body>
<Main>
{props.children}
</Main>
<Scripts />
</body>
</html>
);
}

export default Document;
6 changes: 6 additions & 0 deletions examples/routes-generate/src/pages/about.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as React from 'react';
import { Link } from 'ice';

export default function About() {
return <><h2>About</h2><Link to="/">home</Link></>;
}
7 changes: 7 additions & 0 deletions examples/routes-generate/src/pages/dashboard/a.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react';

export default () => {
return (
<h3>A page</h3>
);
};
7 changes: 7 additions & 0 deletions examples/routes-generate/src/pages/dashboard/b.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react';

export default () => {
return (
<h3>B page</h3>
);
};
7 changes: 7 additions & 0 deletions examples/routes-generate/src/pages/dashboard/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react';

export default () => {
return (
<div>Index</div>
);
};
15 changes: 15 additions & 0 deletions examples/routes-generate/src/pages/dashboard/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as React from 'react';
import { Outlet, Link } from 'ice';

export default () => {
return (
<div>
<h2>Dashboard</h2>
<ul>
<li><Link to="/dashboard/a">a</Link></li>
<li><Link to="/dashboard/b">b</Link></li>
</ul>
<Outlet />
</div>
);
};
13 changes: 13 additions & 0 deletions examples/routes-generate/src/pages/detail/$id.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';
import { useParams, Link } from 'ice';

export default function DetailId() {
const params = useParams();

return (
<div>
<h2>Detail id: {params.id}</h2>
<Link to="/detail">Back to Detail</Link>
</div>
);
}
14 changes: 14 additions & 0 deletions examples/routes-generate/src/pages/detail/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';
import { Link } from 'ice';

export default function Detail() {
return (
<div>
<h2>Detail</h2>
<ul>
<li><Link to="/detail/join">join</Link></li>
<li><Link to="/detail/dashboard">dashboard</Link></li>
</ul>
</div>
);
}
15 changes: 15 additions & 0 deletions examples/routes-generate/src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as React from 'react';
import { Link } from 'ice';

export default function Home() {
return (
<>
<h2>Home</h2>
<ul>
<li><Link to="/about-me">about</Link></li>
<li><Link to="/detail">detail</Link></li>
<li><Link to="/dashboard">dashboard</Link></li>
</ul>
</>
);
}
11 changes: 11 additions & 0 deletions examples/routes-generate/src/pages/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as React from 'react';
import { Outlet } from 'ice';

export default () => {
return (
<div>
<h1>Layout</h1>
<Outlet />
</div>
);
};
6 changes: 6 additions & 0 deletions examples/routes-generate/src/pages/products.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as React from 'react';
import { Link } from 'ice';

export default function Products() {
return <><h2>Products Page</h2><Link to="/">home</Link></>;
}
32 changes: 32 additions & 0 deletions examples/routes-generate/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"compileOnSave": false,
"buildOnSave": false,
"compilerOptions": {
"baseUrl": ".",
"outDir": "build",
"module": "esnext",
"target": "es6",
"jsx": "react",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"lib": ["es6", "dom"],
"sourceMap": true,
"allowJs": true,
"rootDir": "./",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": false,
"importHelpers": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true,
"skipLibCheck": true,
"paths": {
"@/*": ["./src/*"],
"ice": [".ice"]
}
},
"include": ["src", ".ice", "ice.config.*"],
"exclude": ["node_modules", "build", "public"]
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"semver": "^7.3.5",
"stylelint": "^14.3.0",
"typescript": "^4.5.5",
"vitest": "^0.8.4"
"vitest": "^0.9.2"
},
"packageManager": "pnpm"
}
2 changes: 1 addition & 1 deletion packages/build-webpack-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
},
"devDependencies": {
"@ice/types": "^1.0.0",
"build-scripts": "^2.0.0-15",
"build-scripts": "^2.0.0-16",
"webpack": "^5.69.1",
"webpack-dev-server": "^4.7.4"
}
Expand Down
2 changes: 1 addition & 1 deletion packages/build-webpack-config/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function getEntry(rootDir: string) {
}
return {
runtime: ['react', 'react-dom', '@ice/runtime'],
index: {
main: {
import: [entryFile],
dependOn: 'runtime',
},
Expand Down
2 changes: 1 addition & 1 deletion packages/ice/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"@ice/runtime": "^1.0.0",
"@ice/webpack-config": "^1.0.0",
"address": "^1.1.2",
"build-scripts": "^2.0.0-15",
"build-scripts": "^2.0.0-16",
"chalk": "^4.0.0",
"commander": "^9.0.0",
"consola": "^2.15.3",
Expand Down
32 changes: 17 additions & 15 deletions packages/ice/src/createService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,31 +32,16 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt
const templateDir = path.join(__dirname, '../template/');
const configFile = 'ice.config.(mts|mjs|ts|js|cjs|json)';
const dataCache = new Map<string, string>();

const routesRenderData = generateRoutesInfo(rootDir);
dataCache.set('routes', JSON.stringify(routesRenderData));

const generator = new Generator({
rootDir,
targetDir,
defaultRenderData: {
...routesRenderData,
},
// add default template of ice
templates: [templateDir],
});

const { addWatchEvent, removeWatchEvent } = createWatch({
watchDir: rootDir,
command,
watchEvents: getWatchEvents({
generator,
rootDir,
targetDir,
templateDir,
configFile,
cache: dataCache,
}),
});

const generatorAPI = {
Expand All @@ -72,6 +57,7 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt
addRenderFile: generator.addRenderFile,
addRenderTemplate: generator.addTemplateFiles,
};

const ctx = new Context<any, ExtendsPluginAPI>({
rootDir,
command,
Expand All @@ -90,16 +76,32 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt
},
});
await ctx.resolveConfig();
const { userConfig: { routes: routesConfig } } = ctx;
const routesRenderData = generateRoutesInfo(rootDir, routesConfig);
generator.modifyRenderData((renderData) => ({
...renderData,
...routesRenderData,
}));
dataCache.set('routes', JSON.stringify(routesRenderData.routeManifest));

const runtimeModules = getRuntimeModules(ctx.getAllPlugin());
generator.modifyRenderData((renderData) => ({
...renderData,
runtimeModules,
}));
await ctx.setup();

// render template before webpack compile
const renderStart = new Date().getTime();

generator.render();

addWatchEvent(
...getWatchEvents({ generator, targetDir, templateDir, cache: dataCache, ctx }),
);

consola.debug('template render cost:', new Date().getTime() - renderStart);

// define runtime env before get webpack config
defineRuntimeEnv();
const compileIncludes = runtimeModules.map(({ name }) => `${name}/runtime`);
Expand Down
15 changes: 9 additions & 6 deletions packages/ice/src/getWatchEvents.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,34 @@
import * as path from 'path';
import consola from 'consola';
import type { WatchEvent } from '@ice/types/esm/plugin.js';
import type { Context } from 'build-scripts';
import type { Config } from '@ice/types';
import { generateRoutesInfo } from './routes.js';
import type Generator from './service/runtimeGenerator';

interface Options {
rootDir: string;
targetDir: string;
templateDir: string;
configFile: string;
generator: Generator;
cache: Map<string, string>;
ctx: Context<Config>;
}

const getWatchEvents = (options: Options): WatchEvent[] => {
const { rootDir, generator, targetDir, templateDir, configFile, cache } = options;
const { generator, targetDir, templateDir, cache, ctx } = options;
const { userConfig: { routes: routesConfig }, configFile, rootDir } = ctx;
const watchRoutes: WatchEvent = [
/src\/pages\/?[\w*-:.$]+$/,
(eventName: string) => {
if (eventName === 'add' || eventName === 'unlink') {
const routesRenderData = generateRoutesInfo(rootDir);
const routesRenderData = generateRoutesInfo(rootDir, routesConfig);
const stringifiedData = JSON.stringify(routesRenderData);
if (cache.get('routes') !== stringifiedData) {
cache.set('routes', stringifiedData);
consola.debug('[event]', `routes data regenerated: ${stringifiedData}`);
generator.renderFile(
path.join(templateDir, 'routes.ts.ejs'),
path.join(rootDir, targetDir, 'route.ts'),
path.join(rootDir, targetDir, 'routes.ts'),
routesRenderData,
);
generator.renderFile(
Expand All @@ -38,6 +40,7 @@ const getWatchEvents = (options: Options): WatchEvent[] => {
}
},
];

const watchGlobalStyle: WatchEvent = [
/src\/global.(scss|less|css)/,
(event: string, filePath: string) => {
Expand All @@ -49,7 +52,7 @@ const getWatchEvents = (options: Options): WatchEvent[] => {
];

const watchConfigFile: WatchEvent = [
new RegExp(configFile),
new RegExp((typeof configFile === 'string' ? [configFile] : configFile).join('|')),
(event: string, filePath: string) => {
if (event === 'change') {
consola.warn(`Found a change in ${path.basename(filePath)}. Restart the dev server to see the changes in effect.`);
Expand Down
Loading

0 comments on commit d19f21e

Please sign in to comment.