') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); feat: generate qwik starter from QwikCity demo (npm create qwik@latest) by Oyemade · Pull Request #262 · thisdot/starter.dev · GitHub
Skip to content
Closed
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
4 changes: 4 additions & 0 deletions .angulardoc.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
{
"repoId": "89a60295-eef2-4537-9923-754797971f01",
"lastSync": 0
}
30 changes: 30 additions & 0 deletions starters/qwik-express/.eslintignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
**/*.log
**/.DS_Store
*.
.vscode/settings.json
.history
.yarn
bazel-*
bazel-bin
bazel-out
bazel-qwik
bazel-testlogs
dist
dist-dev
lib
etc
external
node_modules
temp
tsc-out
tsdoc-metadata.json
target
output
rollup.config.js
build
.cache
.vscode
.rollup.cache
dist
tsconfig.tsbuildinfo
vite.config.ts
40 changes: 40 additions & 0 deletions starters/qwik-express/.eslintrc.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
module.exports = {
root: true,
env: {
browser: true,
es2021: true,
node: true,
},
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:qwik/recommended',
],
parser: '@typescript-eslint/parser',
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
ecmaVersion: 2021,
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
},
plugins: ['@typescript-eslint'],
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-inferrable-types': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-empty-interface': 'off',
'@typescript-eslint/no-namespace': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-this-alias': 'off',
'@typescript-eslint/ban-types': 'off',
'@typescript-eslint/ban-ts-comment': 'off',
'prefer-spread': 'off',
'no-case-declarations': 'off',
'no-console': 'off',
'@typescript-eslint/no-unused-vars': ['error'],
},
};
35 changes: 35 additions & 0 deletions starters/qwik-express/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
# Build
build
dist
lib
server
functions/**/*.js

# Development
node_modules

# Cache
.cache
.mf
.vscode
.rollup.cache
tsconfig.tsbuildinfo

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

# Editor
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
23 changes: 23 additions & 0 deletions starters/qwik-express/.prettierignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
**/*.log
**/.DS_Store
*.
.vscode/settings.json
.history
.yarn
dist
dist-dev
etc
external
node_modules
temp
tsc-out
tsdoc-metadata.json
target
output
rollup.config.js
build
.cache
.vscode
.rollup.cache
dist
tsconfig.tsbuildinfo
71 changes: 71 additions & 0 deletions starters/qwik-express/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
# Qwik qwik-express ⚡️

- Starter with built-in routing, powered by Qwik City
- Vite.js tooling.
- Express.js server.
- Prettier code formatter.

## Development Builds

### Client only

During development, the index.html is not a result of server-side rendering, but rather the Qwik app is built using client-side JavaScript only. This is ideal for development with Vite and its ability to reload modules quickly and on-demand. However, this mode is only for development and does not showcase "how" Qwik works since JavaScript is required to execute, and Vite imports many development modules for the app to work.

```
npm run dev
```

### Server-side Rendering (SSR) and Client

Server-side rendered index.html, with client-side modules prefetched and loaded by the browser. This can be used to test out server-side rendered content during development, but will be slower than the client-only development builds.

```
npm run dev.ssr
```

## Production Builds

A production build should generate the client and server modules by running both client and server build commands.

```
npm run build
```

### Client Modules

Production build that creates only the client-side modules that are dynamically imported by the browser.

```
npm run build.client
```

### Server Modules

Production build that creates the server-side render (SSR) module that is used by the server to render the HTML.

```
npm run build.ssr
```

## Express Server

This app has a minimal [Express server](https://expressjs.com/) implementation. After running a full build, you can preview the build using the command:

```
npm run serve
```

Then visit [http://localhost:8080/](http://localhost:8080/)

--------------------

## Related

- [Qwik Docs](https://qwik.builder.io/)
- [Qwik Github](https://github.com/BuilderIO/qwik)
- [@QwikDev](https://twitter.com/QwikDev)
- [Discord](https://qwik.builder.io/chat)
- [Vite](https://vitejs.dev/)
- [Partytown](https://partytown.builder.io/)
- [Mitosis](https://github.com/BuilderIO/mitosis)
- [Builder.io](https://www.builder.io/)
40 changes: 40 additions & 0 deletions starters/qwik-express/package.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
{
"name": "qwik-express",
"description": "Starter with built-in routing, powered by Qwik City Vite.js tooling. Express.js server. Prettier code formatter.",
"scripts": {
"build": "npm run typecheck && npm run build.client && npm run build.ssr",
"build.client": "vite build",
"build.ssr": "vite build --ssr src/entry.express.tsx",
"dev": "vite",
"dev.debug": "node --inspect-brk node_modules/vite/bin/vite.js --mode ssr",
"dev.ssr": "node --inspect node_modules/vite/bin/vite.js --mode ssr",
"fmt": "prettier --write .",
"fmt.check": "prettier --check .",
"lint": "eslint \"src/**/*.ts*\"",
"serve": "node server/entry.express.js",
"start": "npm run dev",
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"@builder.io/qwik": "0.0.33",
"@builder.io/qwik-city": "0.0.13",
"@types/eslint": "8.4.2",
"@types/express": "4.17.13",
"@types/node": "latest",
"@typescript-eslint/eslint-plugin": "5.27.0",
"@typescript-eslint/parser": "5.27.0",
"eslint": "8.16.0",
"eslint-plugin-qwik": "0.0.33",
"express": "4.17.3",
"node-fetch": "2.6.7",
"prettier": "2.6.2",
"typescript": "4.7.2",
"vite": "2.9.9"
},
"engines": {
"node": ">=14"
},
"homepage": "https://qwik.builder.io/",
"license": "",
"private": true
}
2 changes: 2 additions & 0 deletions starters/qwik-express/public/_headers
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
/build/*
Cache-Control: public, max-age=31536000, s-maxage=31536000, immutable
Binary file addedstarters/qwik-express/public/favicon.ico
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions starters/qwik-express/public/favicons/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions starters/qwik-express/public/logos/qwik-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions starters/qwik-express/public/logos/qwik.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions starters/qwik-express/src/components/app/app.tsx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
import { component$, Host } from '@builder.io/qwik';
import { Page } from '../page/page';
import { useQwikCity } from '@builder.io/qwik-city';

export const App = component$(() => {
useQwikCity();

return (
<Host>
<Page />
</Host>
);
});
19 changes: 19 additions & 0 deletions starters/qwik-express/src/components/counter/counter.tsx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
import { component$, useScopedStyles$, useStore } from '@builder.io/qwik';

export const Counter = component$(() => {
const store = useStore({ count: 0 });
useScopedStyles$(`
.counter {
border: 3px solid #1474ff;
padding: 10px;
border-radius: 10px;
color: #1474ff;
}
`);

return (
<button class="counter" type="button" onClick$={() => store.count++}>
Increment {store.count}
</button>
);
});
5 changes: 5 additions & 0 deletions starters/qwik-express/src/components/footer/footer.css
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
.docs footer nav a {
@apply text-slate-600;
@apply no-underline;
@apply hover:underline;
}
19 changes: 19 additions & 0 deletions starters/qwik-express/src/components/footer/footer.tsx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
import { component$, Host, useScopedStyles$ } from '@builder.io/qwik';
import styles from './footer.css?inline';

export const Footer = component$(
() => {
useScopedStyles$(styles);

return (
<Host>
<div>
<span>Made with ♡ by the </span>
<a href="https://www.builder.io/">Builder.io</a>
<span> team</span>
</div>
</Host>
);
},
{ tagName: 'footer' }
);
5 changes: 5 additions & 0 deletions starters/qwik-express/src/components/header/header.css
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
header {
background: #1474ff;
padding: 30px;
color: white;
}
21 changes: 21 additions & 0 deletions starters/qwik-express/src/components/header/header.tsx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
import { component$, Host, useScopedStyles$ } from '@builder.io/qwik';
import styles from './header.css?inline';

export const Header = component$(
() => {
useScopedStyles$(styles);

return (
<Host>
<div class="header-inner">
<div className="header-logo">
<a href="/">
<h1>Your Qwikcity site</h1>
</a>
</div>
</div>
</Host>
);
},
{ tagName: 'header' }
);
24 changes: 24 additions & 0 deletions starters/qwik-express/src/components/page/page.tsx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
import { component$ } from '@builder.io/qwik';
import { useHeadMeta, usePage } from '@builder.io/qwik-city';
import NotFound from '../../layouts/not-found/not-found';

export const Page = component$(() => {
const page = usePage();
if (page) {
const attrs = page.attributes;
const Layout = page.layout;
const Content = page.content;

useHeadMeta({
title: attrs.title + ' - Qwik',
description: attrs.description,
});

return (
<Layout>
<Content />
</Layout>
);
}
return <NotFound />;
});
12 changes: 12 additions & 0 deletions starters/qwik-express/src/components/sidebar/sidebar.css
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
aside {
padding: 10px;
}

.menu h5 {
font-size: 18px;
font-weight: 800;
}

.menu li a {
text-decoration: underline;
}
Loading