Skip to content
This repository was archived by the owner on Dec 13, 2025. It is now read-only.

Commit 9f07384

Browse files
Add files via upload
1 parent e137a9f commit 9f07384

34 files changed

+6667
-0
lines changed

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
This is the svelteionic template bootstraped by sapper.
2+
3+
Make sure to change the appID in the capacitor.config.json
4+
5+
# Installing the dependencies
6+
Enter the following command to install the dependencies:
7+
npm i or yarn i (Based on your package manager)
8+
9+
10+
# Starting the server
11+
enter the following commandd into your cmd/cli:
12+
[<br>]
13+
npm dev
14+
15+
# Building the app
16+
Enter the follwoing command to build your app:
17+
[<br>]
18+
ionic build
19+
20+
# Running the app in android studio
21+
Type the following code in your cmd/cli to run the app in Android Studio:
22+
[<br>]
23+
Make sure to set the set Android Gradle Plugin Version as 3.6.1 and Gradle version as 6.2.1 in the Project Structure from the file menu of Android Studio oor your app may not compile.
24+
[<br>]
25+
ionic build
26+
[<br>]
27+
ionic cap open android

capacitor.config.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"appId": "com.technicalfriend.svelteionic",
3+
"appName": "svelteIonic",
4+
"webDir": "__sapper__\\export",
5+
"bundledWebRuntime": false
6+
}

ionic.config.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "svelteIonic",
3+
"integrations": {
4+
"capacitor": {}
5+
},
6+
"type": "custom"
7+
}

package.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"name": "svelteionic",
3+
"description": "svelte+ionic",
4+
"version": "0.0.1",
5+
"scripts": {
6+
"dev": "sapper dev --hot=false",
7+
"build": "sapper build",
8+
"export": "sapper export",
9+
"start": "node __sapper__/build",
10+
"ionic:build": "sapper build && sapper export"
11+
},
12+
"dependencies": {
13+
"@capacitor/android": "3.2.5",
14+
"@capacitor/app": "^1.0.5",
15+
"@capacitor/core": "^3.2.5",
16+
"@capacitor/haptics": "^1.1.2",
17+
"@capacitor/keyboard": "^1.1.2",
18+
"@capacitor/status-bar": "^1.0.5",
19+
"compression": "^1.7.1",
20+
"polka": "next",
21+
"sirv": "^1.0.0"
22+
},
23+
"devDependencies": {
24+
"@capacitor/cli": "^3.2.5",
25+
"css-loader": "^6.4.0",
26+
"file-loader": "^6.0.0",
27+
"sapper": "^0.28.0",
28+
"style-loader": "^2.0.0",
29+
"svelte": "^3.17.3",
30+
"svelte-loader": "^3.0.0",
31+
"webpack": "^4.46.0",
32+
"webpack-modules": "^1.0.0"
33+
}
34+
}

scripts/setupTypeScript.js

Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
/**
2+
* Run this script to convert the project to TypeScript. This is only guaranteed to work
3+
* on the unmodified default template; if you have done code changes you are likely need
4+
* to touch up the generated project manually.
5+
*/
6+
7+
// @ts-check
8+
const fs = require('fs');
9+
const path = require('path');
10+
const { argv } = require('process');
11+
12+
const projectRoot = argv[2] || path.join(__dirname, '..');
13+
14+
const isRollup = fs.existsSync(path.join(projectRoot, "rollup.config.js"));
15+
16+
function warn(message) {
17+
console.warn('Warning: ' + message);
18+
}
19+
20+
function replaceInFile(fileName, replacements) {
21+
if (fs.existsSync(fileName)) {
22+
let contents = fs.readFileSync(fileName, 'utf8');
23+
let hadUpdates = false;
24+
25+
replacements.forEach(([from, to]) => {
26+
const newContents = contents.replace(from, to);
27+
28+
const isAlreadyApplied = typeof to !== 'string' || contents.includes(to);
29+
30+
if (newContents !== contents) {
31+
contents = newContents;
32+
hadUpdates = true;
33+
} else if (!isAlreadyApplied) {
34+
warn(`Wanted to update "${from}" in ${fileName}, but did not find it.`);
35+
}
36+
});
37+
38+
if (hadUpdates) {
39+
fs.writeFileSync(fileName, contents);
40+
} else {
41+
console.log(`${fileName} had already been updated.`);
42+
}
43+
} else {
44+
warn(`Wanted to update ${fileName} but the file did not exist.`);
45+
}
46+
}
47+
48+
function createFile(fileName, contents) {
49+
if (fs.existsSync(fileName)) {
50+
warn(`Wanted to create ${fileName}, but it already existed. Leaving existing file.`);
51+
} else {
52+
fs.writeFileSync(fileName, contents);
53+
}
54+
}
55+
56+
function addDepsToPackageJson() {
57+
const pkgJSONPath = path.join(projectRoot, 'package.json');
58+
const packageJSON = JSON.parse(fs.readFileSync(pkgJSONPath, 'utf8'));
59+
packageJSON.devDependencies = Object.assign(packageJSON.devDependencies, {
60+
...(isRollup ? { '@rollup/plugin-typescript': '^6.0.0' } : { 'ts-loader': '^8.0.4' }),
61+
'@tsconfig/svelte': '^1.0.10',
62+
'@types/compression': '^1.7.0',
63+
'@types/node': '^14.11.1',
64+
'@types/polka': '^0.5.1',
65+
'svelte-check': '^1.0.46',
66+
'svelte-preprocess': '^4.3.0',
67+
tslib: '^2.0.1',
68+
typescript: '^4.0.3'
69+
});
70+
71+
// Add script for checking
72+
packageJSON.scripts = Object.assign(packageJSON.scripts, {
73+
validate: 'svelte-check --ignore src/node_modules/@sapper'
74+
});
75+
76+
// Write the package JSON
77+
fs.writeFileSync(pkgJSONPath, JSON.stringify(packageJSON, null, ' '));
78+
}
79+
80+
function changeJsExtensionToTs(dir) {
81+
const elements = fs.readdirSync(dir, { withFileTypes: true });
82+
83+
for (let i = 0; i < elements.length; i++) {
84+
if (elements[i].isDirectory()) {
85+
changeJsExtensionToTs(path.join(dir, elements[i].name));
86+
} else if (elements[i].name.match(/^[^_]((?!json).)*js$/)) {
87+
fs.renameSync(path.join(dir, elements[i].name), path.join(dir, elements[i].name).replace('.js', '.ts'));
88+
}
89+
}
90+
}
91+
92+
function updateSingleSvelteFile({ view, vars, contextModule }) {
93+
replaceInFile(path.join(projectRoot, 'src', `${view}.svelte`), [
94+
[/(?:<script)(( .*?)*?)>/gm, (m, attrs) => `<script${attrs}${!attrs.includes('lang="ts"') ? ' lang="ts"' : ''}>`],
95+
...(vars ? vars.map(({ name, type }) => [`export let ${name};`, `export let ${name}: ${type};`]) : []),
96+
...(contextModule ? contextModule.map(({ js, ts }) => [js, ts]) : [])
97+
]);
98+
}
99+
100+
// Switch the *.svelte file to use TS
101+
function updateSvelteFiles() {
102+
[
103+
{
104+
view: 'components/Nav',
105+
vars: [{ name: 'segment', type: 'string' }]
106+
},
107+
{
108+
view: 'routes/_layout',
109+
vars: [{ name: 'segment', type: 'string' }]
110+
},
111+
{
112+
view: 'routes/_error',
113+
vars: [
114+
{ name: 'status', type: 'number' },
115+
{ name: 'error', type: 'Error' }
116+
]
117+
},
118+
{
119+
view: 'routes/blog/index',
120+
vars: [{ name: 'posts', type: '{ slug: string; title: string, html: any }[]' }],
121+
contextModule: [
122+
{
123+
js: '.then(r => r.json())',
124+
ts: '.then((r: { json: () => any; }) => r.json())'
125+
},
126+
{
127+
js: '.then(posts => {',
128+
ts: '.then((posts: { slug: string; title: string, html: any }[]) => {'
129+
}
130+
]
131+
},
132+
{
133+
view: 'routes/blog/[slug]',
134+
vars: [{ name: 'post', type: '{ slug: string; title: string, html: any }' }]
135+
}
136+
].forEach(updateSingleSvelteFile);
137+
}
138+
139+
function updateRollupConfig() {
140+
// Edit rollup config
141+
replaceInFile(path.join(projectRoot, 'rollup.config.js'), [
142+
// Edit imports
143+
[
144+
/'rollup-plugin-terser';\n(?!import sveltePreprocess)/,
145+
`'rollup-plugin-terser';
146+
import sveltePreprocess from 'svelte-preprocess';
147+
import typescript from '@rollup/plugin-typescript';
148+
`
149+
],
150+
// Edit inputs
151+
[
152+
/(?<!THIS_IS_UNDEFINED[^\n]*\n\s*)onwarn\(warning\);/,
153+
`(warning.code === 'THIS_IS_UNDEFINED') ||\n\tonwarn(warning);`
154+
],
155+
[/input: config.client.input\(\)(?!\.replace)/, `input: config.client.input().replace(/\\.js$/, '.ts')`],
156+
[
157+
/input: config.server.input\(\)(?!\.replace)/,
158+
`input: { server: config.server.input().server.replace(/\\.js$/, ".ts") }`
159+
],
160+
[
161+
/input: config.serviceworker.input\(\)(?!\.replace)/,
162+
`input: config.serviceworker.input().replace(/\\.js$/, '.ts')`
163+
],
164+
// Add preprocess
165+
[/compilerOptions/g, 'preprocess: sveltePreprocess({ sourceMap: dev }),\n\t\t\t\tcompilerOptions'],
166+
// Add TypeScript
167+
[/commonjs\(\)(?!,\n\s*typescript)/g, 'commonjs(),\n\t\t\ttypescript({ sourceMap: dev })']
168+
]);
169+
}
170+
171+
function updateWebpackConfig() {
172+
// Edit webpack config
173+
replaceInFile(path.join(projectRoot, 'webpack.config.js'), [
174+
// Edit imports
175+
[
176+
/require\('webpack-modules'\);\n(?!const sveltePreprocess)/,
177+
`require('webpack-modules');\nconst sveltePreprocess = require('svelte-preprocess');\n`
178+
],
179+
// Edit extensions
180+
[
181+
/\['\.mjs', '\.js', '\.json', '\.svelte', '\.html'\]/,
182+
`['.mjs', '.js', '.ts', '.json', '.svelte', '.html']`
183+
],
184+
// Edit entries
185+
[
186+
/entry: config\.client\.entry\(\)/,
187+
`entry: { main: config.client.entry().main.replace(/\\.js$/, '.ts') }`
188+
],
189+
[
190+
/entry: config\.server\.entry\(\)/,
191+
`entry: { server: config.server.entry().server.replace(/\\.js$/, '.ts') }`
192+
],
193+
[
194+
/entry: config\.serviceworker\.entry\(\)/,
195+
`entry: { 'service-worker': config.serviceworker.entry()['service-worker'].replace(/\\.js$/, '.ts') }`
196+
],
197+
[
198+
/loader: 'svelte-loader',\n\t\t\t\t\t\toptions: {/g,
199+
'loader: \'svelte-loader\',\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tpreprocess: sveltePreprocess({ sourceMap: dev }),'
200+
],
201+
// Add TypeScript rules for client and server
202+
[
203+
/module: {\n\s*rules: \[\n\s*(?!{\n\s*test: \/\\\.ts\$\/)/g,
204+
`module: {\n\t\t\trules: [\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.ts$/,\n\t\t\t\t\tloader: 'ts-loader'\n\t\t\t\t},\n\t\t\t\t`
205+
],
206+
// Add TypeScript rules for serviceworker
207+
[
208+
/output: config\.serviceworker\.output\(\),\n\s*(?!module)/,
209+
`output: config.serviceworker.output(),\n\t\tmodule: {\n\t\t\trules: [\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.ts$/,\n\t\t\t\t\tloader: 'ts-loader'\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t`
210+
],
211+
// Edit outputs
212+
[
213+
/output: config\.serviceworker\.output\(\),\n\s*(?!resolve)/,
214+
`output: config.serviceworker.output(),\n\t\tresolve: { extensions: ['.mjs', '.js', '.ts', '.json'] },\n\t\t`
215+
]
216+
]);
217+
}
218+
219+
function updateServiceWorker() {
220+
replaceInFile(path.join(projectRoot, 'src', 'service-worker.ts'), [
221+
[`shell.concat(files);`, `(shell as string[]).concat(files as string[]);`],
222+
[`self.skipWaiting();`, `((self as any) as ServiceWorkerGlobalScope).skipWaiting();`],
223+
[`self.clients.claim();`, `((self as any) as ServiceWorkerGlobalScope).clients.claim();`],
224+
[`fetchAndCache(request)`, `fetchAndCache(request: Request)`],
225+
[`self.addEventListener('activate', event =>`, `self.addEventListener('activate', (event: ExtendableEvent) =>`],
226+
[`self.addEventListener('install', event =>`, `self.addEventListener('install', (event: ExtendableEvent) =>`],
227+
[`addEventListener('fetch', event =>`, `addEventListener('fetch', (event: FetchEvent) =>`],
228+
]);
229+
}
230+
231+
function createTsConfig() {
232+
const tsconfig = `{
233+
"extends": "@tsconfig/svelte/tsconfig.json",
234+
"compilerOptions": {
235+
"lib": ["DOM", "ES2017", "WebWorker"]
236+
},
237+
"include": ["src/**/*", "src/node_modules/**/*"],
238+
"exclude": ["node_modules/*", "__sapper__/*", "static/*"]
239+
}`;
240+
241+
createFile(path.join(projectRoot, 'tsconfig.json'), tsconfig);
242+
}
243+
244+
// Adds the extension recommendation
245+
function configureVsCode() {
246+
const dir = path.join(projectRoot, '.vscode');
247+
248+
if (!fs.existsSync(dir)) {
249+
fs.mkdirSync(dir);
250+
}
251+
252+
createFile(path.join(projectRoot, '.vscode', 'extensions.json'), `{"recommendations": ["svelte.svelte-vscode"]}`);
253+
}
254+
255+
function deleteThisScript() {
256+
fs.unlinkSync(path.join(__filename));
257+
258+
// Check for Mac's DS_store file, and if it's the only one left remove it
259+
const remainingFiles = fs.readdirSync(path.join(__dirname));
260+
if (remainingFiles.length === 1 && remainingFiles[0] === '.DS_store') {
261+
fs.unlinkSync(path.join(__dirname, '.DS_store'));
262+
}
263+
264+
// Check if the scripts folder is empty
265+
if (fs.readdirSync(path.join(__dirname)).length === 0) {
266+
// Remove the scripts folder
267+
fs.rmdirSync(path.join(__dirname));
268+
}
269+
}
270+
271+
console.log(`Adding TypeScript with ${isRollup ? "Rollup" : "webpack" }...`);
272+
273+
addDepsToPackageJson();
274+
275+
changeJsExtensionToTs(path.join(projectRoot, 'src'));
276+
277+
updateSvelteFiles();
278+
279+
if (isRollup) {
280+
updateRollupConfig();
281+
} else {
282+
updateWebpackConfig();
283+
}
284+
285+
updateServiceWorker();
286+
287+
createTsConfig();
288+
289+
configureVsCode();
290+
291+
// Delete this script, but not during testing
292+
if (!argv[2]) {
293+
deleteThisScript();
294+
}
295+
296+
console.log('Converted to TypeScript.');
297+
298+
if (fs.existsSync(path.join(projectRoot, 'node_modules'))) {
299+
console.log(`
300+
Next:
301+
1. run 'npm install' again to install TypeScript dependencies
302+
2. run 'npm run build' for the @sapper imports in your project to work
303+
`);
304+
}

0 commit comments

Comments
 (0)