Skip to content

Commit

Permalink
Tools(inline): update docs & fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
robisim74 committed Nov 17, 2022
1 parent 99a1b5c commit c6ab427
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 60 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -306,10 +306,10 @@ npm run serve
```

## What's new
> Released v0.2.0
> Released v0.3.0
- Advanced inlining: [Qwik Speak Inline Vite plugin](./tools/inline.md)
- Extract translations: [Qwik Speak Extract](./tools/extract.md)
- Inline translation data at compile time: [Qwik Speak Inline Vite plugin](./tools/inline.md)

## License
MIT
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"serve": "node server/entry.express",
"start": "vite --open --mode ssr",
"test": "jest ./src/tests ./tools/tests",
"test.e2e": "playwright test",
"test.e2e": "npm run build.app && playwright test",
"test.watch": "jest ./src/tests ./tools/tests --watch",
"qwik": "qwik",
"qwik-speak-extract": "qwik-speak-extract --supportedLangs=en-US,it-IT --sourceFilesPath=src/app"
Expand Down
32 changes: 2 additions & 30 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,43 +64,15 @@ const config: PlaywrightTestConfig = {
...devices['Desktop Safari'],
},
},

/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: {
// ...devices['Pixel 5'],
// },
// },
// {
// name: 'Mobile Safari',
// use: {
// ...devices['iPhone 12'],
// },
// },

/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: {
// channel: 'msedge',
// },
// },
// {
// name: 'Google Chrome',
// use: {
// channel: 'chrome',
// },
// },
],

/* Folder for test artifacts such as screenshots, videos, traces, etc. */
// outputDir: 'test-results/',

/* Run your local dev server before starting the tests */
webServer: {
command: 'npm run dev',
port: 5173,
command: 'npm run serve',
port: 8080,
},
};

Expand Down
5 changes: 4 additions & 1 deletion tools/extract.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Optionally, you can use a default value for the keys. The syntax is `key@@[defau
```
When you use a default value, it will be used as initial value for the key in every translation.

> Note. A key will not be extracted when a function argument is a variable (dynamic).
> Note. A key will not be extracted when a function argument is a variable (dynamic)
#### Naming conventions
If you use scoped translations, the first property will be used as filename:
Expand All @@ -26,6 +26,9 @@ will generate two files for each language:
public/i18n
└───en-US
│ app.json
│ home.json
└───it-IT
app.json
home.json
```
Expand Down
68 changes: 58 additions & 10 deletions tools/inline.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
Make sure that the translation files are only loaded in dev mode, for example:
```typescript
export const loadTranslation$: LoadTranslationFn = $(async (lang: string, asset: string, url?: URL) => {
if (import.meta.env.DEV ) {
if (import.meta.env.DEV) {
// Load translations
}
});
Expand Down Expand Up @@ -63,7 +63,7 @@ When there are translations with dynamic keys or params, you can manage them at
}
});
```
Likewise, you can also create scoped runtime files for the different pages.
Likewise, you can also create scoped runtime files for different pages.

> Note. The `plural` function must be handled as a dynamic translation
Expand All @@ -73,19 +73,67 @@ During the transformation of the modules, and before tree shaking and bundling,
/*#__PURE__*/ _jsx("h2", {
children: t('app.subtitle')
}),
/*#__PURE__*/ _jsx("p", {
children: t('home.greeting', {
name: 'Qwik Speak'
})
}),
```
to:
```javascript
/*#__PURE__*/ _jsx("h2", {
children: $lang() === `it-IT` && `Traduci le tue app Qwik in qualsiasi lingua` || `Translate your Qwik apps into any language`
}),
/*#__PURE__*/ _jsx("p", {
children: $lang() === `it-IT` && `Ciao! Sono ${'Qwik Speak'}` || `Hi! I am ${'Qwik Speak'}`
}),
```
`$lang` is imported and added during compilation, and you can still change locales at runtime without redirecting or reloading the page.

## Advanced inlining
If you have many languages, or long texts, you can further optimize the chunks sent to the browser by enabling the `splitChunks` option :
```typescript
qwikSpeakInline({
basePath: './',
assetsPath: 'public/i18n',
supportedLangs: ['en-US', 'it-IT'],
defaultLang: 'en-US',
splitChunks: true
})
```
In this way the browser chunks are generated one for each language:
```
dist/build
└───en-US
│ q-*.js
└───it-IT
q-*.js
```
Each contains only its own translation:
```javascript
/* @__PURE__ */ Ut("h2", {
children: `Translate your Qwik apps into any language`
}),
```
```javascript
/* @__PURE__ */ Ut("h2", {
children: `Traduci le tue app Qwik in qualsiasi lingua`
}),
```

Qwik uses the `q:base` attribute to determine the base URL for loading the chunks in the browser, so you have to set it in `entry.ssr.tsx` file. For example, if you have a localized router:
```typescript
export function extractBase({ envData }: RenderOptions): string {
const url = new URL(envData!.url);
const lang = config.supportedLocales.find(x => url.pathname.startsWith(`/${x.lang}`))?.lang;

if (!import.meta.env.DEV && lang) {
return '/build/' + lang;
} else {
return '/build';
}
}

export default function (opts: RenderToStreamOptions) {
return renderToStream(<Root />, {
manifest,
...opts,
base: extractBase,
});
}
```

> Note. To update the `q:base` when language changes, you need to navigate to the new localized URL or reload the page. Therefore, it is not possible to use the `changeLocale` function
16 changes: 8 additions & 8 deletions tools/inline/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,12 @@ export function qwikSpeakInline(options: QwikSpeakInlineOptions): Plugin {
if (/\/src\//.test(id) && /\.(js|cjs|mjs|jsx|ts|tsx)$/.test(id)) {
// Filter code
if (/\$translate/.test(code)) {
if (target === 'ssr' || !resolvedOptions.splitChunks) {
const alias = getTranslateAlias(code);
return inline(code, translation, alias, resolvedOptions);
if (target === 'client' && resolvedOptions.splitChunks) {
return inlinePlaceholder(code);
}
else {
/* console.log('');
console.log('');
console.log(code); */
return inlinePlaceholder(code);
const alias = getTranslateAlias(code);
return inline(code, translation, alias, resolvedOptions);
}
}
}
Expand Down Expand Up @@ -362,5 +359,8 @@ export function transpileFn(values: Map<string, string>, supportedLangs: string[
* Add $lang to component
*/
export function addLang(code: string): string {
return code.replace(/^/, 'import { $lang } from "qwik-speak";\n');
if (!/^import\s*\{.*\$lang.*}\s*from\s*/s.test(code)) {
code = code.replace(/^/, 'import { $lang } from "qwik-speak";\n');
}
return code;
}
18 changes: 11 additions & 7 deletions tools/tests/mock.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/* eslint-disable */
export const mockCode = `import { RelativeTime } from "./app/routes/[...lang]/index";
import { Fragment as _Fragment } from "@builder.io/qwik/jsx-runtime";
export const mockCode = `import { Fragment as _Fragment } from "@builder.io/qwik/jsx-runtime";
import { jsx as _jsx } from "@builder.io/qwik/jsx-runtime";
import { jsxs as _jsxs } from "@builder.io/qwik/jsx-runtime";
import { formatDate as fd } from "qwik-speak";
import { formatNumber as fn } from "qwik-speak";
import { plural as p } from "qwik-speak";
import { qrl } from "@builder.io/qwik";
import { relativeTime as rt } from "qwik-speak";
import { $translate as t } from "qwik-speak";
import { useSpeakLocale } from "qwik-speak";
import { useStore } from "@builder.io/qwik";
Expand Down Expand Up @@ -47,7 +47,7 @@ export const s_xJBzwgVGKaQ = ()=>{
children: t('home.increment')
}),
/*#__PURE__*/ _jsx("p", {
children: p(state.count, 'home.devs')
children: p(state.count, 'runtime.devs')
}),
/*#__PURE__*/ _jsx("h3", {
children: t('home.dates')
Expand All @@ -58,7 +58,9 @@ export const s_xJBzwgVGKaQ = ()=>{
timeStyle: 'short'
})
}),
/*#__PURE__*/ _jsx(RelativeTime, {}),
/*#__PURE__*/ _jsx("p", {
children: rt(-1, 'second')
}),
/*#__PURE__*/ _jsx("h3", {
children: t('home.numbers')
}),
Expand All @@ -81,14 +83,14 @@ export const s_xJBzwgVGKaQ = ()=>{
};`;

export const inlinedCode = `import { $lang } from "qwik-speak";
import { RelativeTime } from "./app/routes/[...lang]/index";
import { Fragment as _Fragment } from "@builder.io/qwik/jsx-runtime";
import { jsx as _jsx } from "@builder.io/qwik/jsx-runtime";
import { jsxs as _jsxs } from "@builder.io/qwik/jsx-runtime";
import { formatDate as fd } from "qwik-speak";
import { formatNumber as fn } from "qwik-speak";
import { plural as p } from "qwik-speak";
import { qrl } from "@builder.io/qwik";
import { relativeTime as rt } from "qwik-speak";
import { $translate as t } from "qwik-speak";
import { useSpeakLocale } from "qwik-speak";
import { useStore } from "@builder.io/qwik";
Expand Down Expand Up @@ -127,7 +129,7 @@ export const s_xJBzwgVGKaQ = ()=>{
children: $lang() === \`it-IT\` && \`Incrementa\` || \`Increment\`
}),
/*#__PURE__*/ _jsx("p", {
children: p(state.count, 'home.devs')
children: p(state.count, 'runtime.devs')
}),
/*#__PURE__*/ _jsx("h3", {
children: $lang() === \`it-IT\` && \`Date e tempo relativo\` || \`Dates & relative time\`
Expand All @@ -138,7 +140,9 @@ export const s_xJBzwgVGKaQ = ()=>{
timeStyle: 'short'
})
}),
/*#__PURE__*/ _jsx(RelativeTime, {}),
/*#__PURE__*/ _jsx("p", {
children: rt(-1, 'second')
}),
/*#__PURE__*/ _jsx("h3", {
children: $lang() === \`it-IT\` && \`Numeri e valute\` || \`Numbers & currencies\`
}),
Expand Down
6 changes: 5 additions & 1 deletion vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@ import { qwikSpeakInline } from './tools/inline';

export default defineConfig(() => {
return {
build: {
minify: false
},
plugins: [
qwikCity({
routesDir: './src/app/routes',
}),
qwikVite(),
qwikSpeakInline({
supportedLangs: ['en-US', 'it-IT'],
defaultLang: 'en-US'
defaultLang: 'en-US',
//splitChunks: true
}),
tsconfigPaths(),
],
Expand Down

0 comments on commit c6ab427

Please sign in to comment.