diff --git a/.vscode/settings.json b/.vscode/settings.json index a6fb8014..7c765a9c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,13 +1,17 @@ //vscode import settings for default formatter (typescript && js) - +// using official denoland extension { "deno.enable": true, "deno.lint": true, - "deno.unstable": true, - "[typescript]": { - "editor.defaultFormatter": "denoland.vscode-deno" + "deno.unstable": false, + "editor.codeActionsOnSave": { + "source.fixAll": true, + "source.organizeImports": true }, - "[javascript]": { - "editor.defaultFormatter": "denoland.vscode-deno" + "editor.defaultFormatter": "denoland.vscode-deno", + "editor.formatOnSave": true, + "editor.formatOnPaste": false, + "deno.suggest.imports.hosts": { + "https://deno.land": true } } diff --git a/README.md b/README.md index 4a279702..a7957d18 100644 --- a/README.md +++ b/README.md @@ -24,25 +24,30 @@ ## Overview -- Vue is an approachable, incrementally adoptable JavaScript framework with an exciting ecosystem. Deno is a new runtime environment for JavaScript, built to address the shortcomings of node.js. We wanted to create a tool that let developers easily set up Vue applications in a Deno runtime environment. Meet vno! +- Vue is an approachable, incrementally adoptable JavaScript framework with an + exciting ecosystem. Deno is a new runtime environment for JavaScript, built to + address the shortcomings of node.js. We wanted to create a tool that let + developers easily set up Vue applications in a Deno runtime environment. Meet + vno! ## How to use vno -- You can use the vno Command Line Interface to quickly create a new Vue project in a Deno runtime +- You can use the vno Command Line Interface to quickly create a new Vue project + in a Deno runtime - OR you can use the vno build method to compile an existing Vue file structure into a Deno-legible .js file ### vno installation - vno requires the use of Deno version 1.10 or above -- MacOS: +- MacOS: - Run the following command in your terminal to install vno on your machine. ```bash deno install --allow-net --unstable https://deno.land/x/vno/install/vno.ts ``` -- WSL/Linux: +- WSL/Linux: - Open `/home//bashrc` with your editor of choice. - Add `export PATH="/home//.deno/bin:$PATH` to the end of the file. - Run the following command in your terminal to install vno on your machine. @@ -61,10 +66,11 @@ sudo deno install --allow-net --unstable https://deno.land/x/vno/install/vno.ts 'vno' is the default name. - If you have not already added Deno bin into your path, you will need to do so. - - MacOS: Copy the export path your terminal returns and paste it into your terminal - - WSL/Linux: Replace `root` with your username and paste it into your terminal: - `export PATH="/home//.deno/bin:$PATH"` - ![install gif](https://media.giphy.com/media/LVokebNuReGJuwU13R/giphy.gif) + - MacOS: Copy the export path your terminal returns and paste it into your + terminal + - WSL/Linux: Replace `root` with your username and paste it into your + terminal: `export PATH="/home//.deno/bin:$PATH"` + ![install gif](https://media.giphy.com/media/LVokebNuReGJuwU13R/giphy.gif) ### a quick word about permissions @@ -76,8 +82,8 @@ sudo deno install --allow-net --unstable https://deno.land/x/vno/install/vno.ts `--allow-write` - If you decide not to flag permissions at installation, you will be prompted in the terminal after executing a command. -- If you would like to avoid writing out the permissions altogether, you - can also use the `-A` or `--allow-all` tag +- If you would like to avoid writing out the permissions altogether, you can + also use the `-A` or `--allow-all` tag ### vno config @@ -86,21 +92,23 @@ sudo deno install --allow-net --unstable https://deno.land/x/vno/install/vno.ts ```ts interface Config { - entry: string; - //entry is the path to root component's directory : i.e. './client/' - root: string; - //root is the filename of your root component : i.e. 'App' - vue?: 2 | 3; - //vue is the number 2 or 3 : 2 = vue v2.6.12 (default); 3 = vue v3.0.5 - options?: { - port?: number; - //preferred port for the dev server : defaults to `3000` - title?: string; - //title of your project - hostname?: string; - //preferred host : defaults to `0.0.0.0` - }; - } + entry: string; + //entry is the path to root component's directory : i.e. './client/' + root: string; + //root is the filename of your root component : i.e. 'App' + vue?: 2 | 3; + //vue is the number 2 or 3 : 2 = vue v2.6.12 (default); 3 = vue v3.0.5 + options?: { + port?: number; + //preferred port for the dev server : defaults to `3000` + reloadPort?: number; + // preferred port for dev server reload : defaults to `8080` + title?: string; + //title of your project + hostname?: string; + //preferred host : defaults to `0.0.0.0` + }; +} ``` ## CLI @@ -109,8 +117,11 @@ interface Config { - Project name will become the directory that holds your project (you must CD into project directory after running the `vno create` command). -- If the project name argument is omitted, then the project will be created in the current working directory. -- Using `vno create` will give an option to build out a universal or single page application. Choosing 'SPA' will give you the option of choosing to add Vue Router, as well as choosing between Vue 2 or Vue 3 syntax. +- If the project name argument is omitted, then the project will be created in + the current working directory. +- Using `vno create` will give an option to build out a universal or single page + application. Choosing 'SPA' will give you the option of choosing to add Vue + Router, as well as choosing between Vue 2 or Vue 3 syntax. ```bash vno create [project name] @@ -141,15 +152,19 @@ deno run --allow-read --allow-write --allow-net --unstable https://deno.land/x/v ![vno build](https://i.ibb.co/jgRFXvc/vno-build.gif) -**Scoped styling for CSS is currently not supported, but will be added to future builds** +**Scoped styling for CSS is currently not supported, but will be added to future +builds** ### run a build on a project AND create a server configured for SSR -- To invoke the build method and dynamically create bundled JS and CSS files, along with a server.ts for server side rendering your application, type the following into the terminal: +- To invoke the build method and dynamically create bundled JS and CSS files, + along with a server.ts for server side rendering your application, type the + following into the terminal: ```bash vno build --ssr ``` + _OR_ ```bash @@ -162,7 +177,9 @@ deno run --allow-read --allow-write --allow-net --unstable https://deno.land/x/v - Running the dev server dynamically runs a new build and runs the application on a module hosted server. -- Native `vno run dev` command automatically enables live reload. Using Live Reload injects a WebSocket connection to build.js. Remove it with: `vno run build` +- Native `vno run dev` command automatically enables live reload. Using Live + Reload injects a WebSocket connection to build.js. Remove it with: + `vno run build` - Invoke the dev server using the following commands: ```bash @@ -177,8 +194,6 @@ deno run --allow-read --allow-write --allow-net --unstable https://deno.land/x/v ![vno run dev & live reload](https://i.ibb.co/c15qK5J/final-live-gif.gif) - - # vno as an API ### initializing your application with the api @@ -188,7 +203,7 @@ deno run --allow-read --allow-write --allow-net --unstable https://deno.land/x/v needed The API will search for the config and apply it to your application ```ts -import { Factory } from 'https://deno.land/x/vno/dist/mod.ts'; +import { Factory } from "https://deno.land/x/vno/dist/mod.ts"; const vno = new Factory(); await vno.build(); @@ -221,7 +236,7 @@ await vno.build(); property on the Factory class. ```ts -vno.storage.get('App'); +vno.storage.get("App"); ``` The argument accepted by the get method for storage is the component filename diff --git a/core/cli/commands.ts b/core/cli/commands.ts index 7300c98b..4818debe 100644 --- a/core/cli/commands.ts +++ b/core/cli/commands.ts @@ -40,13 +40,13 @@ export const create = async function (args: string[]): Promise { const components = mutable.length > 0 ? mutable : undefined; if (title) { - const dir = `${Deno.cwd()}/${title}`; + const dir = `${Deno.cwd()}/${title}`; await fs.ensureDir(dir); // checks if dir exists, if not creates it Deno.chdir(dir); // changes current directory to dir } if (appType === "universal") { - fn.green(out.creating);//turns all exports from constants to green in cli + fn.green(out.creating); //turns all exports from constants to green in cli renderProgress(); // displays progress bar @@ -81,7 +81,7 @@ export const build = async function (args: string[]): Promise { : fn.green(`[${serverTs} file located]`); fn.yellow(`=> ${Deno.cwd()}`); - //configPath is cwd/filename (with extention because ts) + //configPath is cwd/filename (with extension because ts) const configPath = `${Deno.cwd()}/${vnoconfig}`; // Deno.readTextFile returns entire contents of configFile as a string const json = await Deno.readTextFile(configPath); @@ -91,7 +91,6 @@ export const build = async function (args: string[]): Promise { await Deno.writeTextFile(configPath, JSON.stringify(res)); } - //if args index 2 is not --ssr const path = !cmnd.buildSsr.test(args[1]) ? args[1] : undefined; if (path) { @@ -118,12 +117,12 @@ export const run = async function (args: string[]): Promise { if (quietArg(args[2]) || quietArg(args[3])) print.QUIET(); // no logo else print.ASCII(); // prints ASCII logo - const { port, hostname } = vno; + const { port, hostname, reloadPort } = vno; if (cmnd.dev.test(args[1])) { //for live reload await vno.build(true); - await runDevServer(port, hostname); + await runDevServer(port, hostname, reloadPort); Deno.exit(0); } else if (cmnd.server.test(args[1])) { @@ -147,9 +146,9 @@ export const flags = function (args: string[]): void { print.ASCII(); print.INFO(info); - + // if help flag is entered, print CMDS and OPTIONS to CLI - if (helpArg) { + if (helpArg) { print.CMDS(info); print.OPTIONS(info); } else console.log("\n"); diff --git a/core/cli/dev.ts b/core/cli/dev.ts index bf9a6a21..95958ffe 100644 --- a/core/cli/dev.ts +++ b/core/cli/dev.ts @@ -1,22 +1,23 @@ import { Application, path, send } from "../utils/deps.ts"; import { WebSocketClient, WebSocketServer } from "../utils/deps.ts"; import * as print from "./stdout.ts"; -import { exec } from "../utils/deps.ts"; import { watchAndRebuild } from "./liveRebuild.ts"; -import { event } from "../utils/events.ts" - - +import { event } from "../utils/events.ts"; export const server: Application = new Application(); -export const runDevServer = async function (port: number, hostname: string) { - const wss = new WebSocketServer(8080); +export const runDevServer = async function ( + port: number, + hostname: string, + reloadport: number, +) { + const wss = new WebSocketServer(reloadport); wss.on("connection", function (ws: WebSocketClient) { - ws.send('[LiveReload is watching...'); + ws.send("[LiveReload is watching..."); // create event listener that listens for "buildDone" event const reloadWindow = () => { console.log("[back to you Client!]"); - ws.send('reload window'); + ws.send("reload window"); event.removeListener("buildDone", reloadWindow); }; @@ -27,7 +28,6 @@ export const runDevServer = async function (port: number, hostname: string) { }); }); - //server route handler server.use(async (ctx, next) => { const { pathname } = ctx.request.url; @@ -60,7 +60,7 @@ export const runDevServer = async function (port: number, hostname: string) { server.addEventListener("listen", () => { print.LISTEN(port, hostname); if (running === false) { - watchAndRebuild({ ssr: false }); + watchAndRebuild({ ssr: false }); running = true; } }); diff --git a/core/dts/factory.d.ts b/core/dts/factory.d.ts index 6b4bf6a1..e4913558 100644 --- a/core/dts/factory.d.ts +++ b/core/dts/factory.d.ts @@ -66,9 +66,9 @@ export interface Config { */ router?: string; - /** - * router - version? what gets passed in as value? - */ + /** + * router - version? what gets passed in as value? + */ options?: { /** * options to further customize vno @@ -78,6 +78,11 @@ export interface Config { * preferred port for dev server * default: 3000 */ + reloadPort?: number; + /** + * preferred port for dev server reload + * default: 8080 + */ title?: string; /** * title of your project @@ -87,7 +92,6 @@ export interface Config { * preferred host * default: "0.0.0.0" */ - }; } export declare namespace Vue { @@ -231,4 +235,4 @@ export declare namespace Router { ref: string | boolean, ): Promise; } -} \ No newline at end of file +} diff --git a/core/factory/Factory.ts b/core/factory/Factory.ts index 62f31958..94062a49 100644 --- a/core/factory/Factory.ts +++ b/core/factory/Factory.ts @@ -20,6 +20,7 @@ export default class Factory { public variable: string; private _config: Config; private _port!: number; + private _reloadport!: number; private _title!: string; private _hostname!: string; private _server!: string; @@ -61,10 +62,14 @@ export default class Factory { //line below returns a "vno.config" config file to this._config, throws err if no config file is found if (!checkOptions(this.config)) { //check if config obj is not null, & config.entry & config.root equal "string" this._config = await configReader() as Config; - } // "config.options?.port" is an example of optional chaining with the safe navigation operator ".?" + } + // "config.options?.port" is an example of optional chaining with the safe navigation operator ".?" if (this.config.options?.port) { this._port = this.config.options.port; } + if (this.config.options?.reloadPort) { + this._reloadport = this.config.options.reloadPort; + } if (this.config.options?.hostname) { this._hostname = this.config.options.hostname; } @@ -77,6 +82,9 @@ export default class Factory { if (this.config.router) { this._router = this.config.router; } + if (this.storage) { + this.storage.config = this._config; + } } /** * createStorage() collects all .vue files @@ -128,7 +136,7 @@ export default class Factory { const decoder = new TextDecoder("utf-8"); const styles = decoder.decode( - Deno.readFileSync(Deno.cwd()+"/vno-build/style.css"), + Deno.readFileSync(Deno.cwd() + "/vno-build/style.css"), ); Deno.writeTextFileSync( @@ -170,6 +178,11 @@ export default class Factory { return 3000; } + get reloadPort() { + if (this._reloadport) return this._reloadport; + return 8080; + } + get hostname() { if (this._hostname) return this._hostname; return "0.0.0.0"; @@ -188,6 +201,6 @@ export default class Factory { // added router 9/21/21 get router() { if (this._router) return this._router; - return "^4.0.0-0" + return "^4.0.0-0"; } } diff --git a/core/factory/Storage.ts b/core/factory/Storage.ts index 6462ef19..022d430c 100644 --- a/core/factory/Storage.ts +++ b/core/factory/Storage.ts @@ -1,4 +1,10 @@ -import { Component, ComponentContainer, Vue, Router } from "../dts/factory.d.ts"; +import { + Component, + ComponentContainer, + Config, + Router, + Vue, +} from "../dts/factory.d.ts"; /** * Storage class follows the Singelton design pattern @@ -11,7 +17,7 @@ export default class Storage { public app: ComponentContainer; // added 9/27 private _router: Router.Version; - + private _config: Config; private static instance: Storage; private constructor() { this.app = {}; @@ -20,11 +26,12 @@ export default class Storage { this.size = 0; // added 9/27 this._router = {}; + this._config = {}; } /** - * an instance is made through the `create` method - * if an instance has already been made, it returns + * an instance is made through the `create` method + * if an instance has already been made, it returns * the original instance */ public static create() { @@ -69,4 +76,12 @@ export default class Storage { set router(router: Router.Version) { this._router = router; } + + get config() { + return this._config; + } + + set config(config: Config) { + this._config = config; + } } diff --git a/core/lib/resolver.ts b/core/lib/resolver.ts index 0d07f2a8..4fd21dc6 100644 --- a/core/lib/resolver.ts +++ b/core/lib/resolver.ts @@ -9,18 +9,18 @@ export const _script: Resolve.Source = async function (data, path, tsCheck) { if (typeof data === "string") { throw new TypeError("invalid arguments"); } -//"^" beginning of line -//"\s" looks for whitespace -//looking for export -//"*" 0 or more -//() capture group: please find any in capture group and also allow you to remember it refer -//to it by $1,2,3 etc.. like postgres $1, $2 for points you want to make dynamic. -//so later you can change the $1 that you can find and replace + //"^" beginning of line + //"\s" looks for whitespace + //looking for export + //"*" 0 or more + //() capture group: please find any in capture group and also allow you to remember it refer + //to it by $1,2,3 etc.. like postgres $1, $2 for points you want to make dynamic. + //so later you can change the $1 that you can find and replace const start = utils.indexOfRegExp(/^\s*(export)/, data); const end = data.lastIndexOf("}"); const trimmed = data.slice(start + 1, end).join("\n"); -//grabed trim a string of key:value pairs and putting it inside object + //grabed trim a string of key:value pairs and putting it inside object let script = tsCheck ? await typescriptCompile(`({ ${trimmed} })`, path) : trimmed as string; @@ -79,7 +79,6 @@ export const _dependants: Resolve.Attrs = function (curr, arr, storage, queue) { } }; - //vno struggles with third party imports in component file. //this collects all potential imports. inserts them at the top of the bundle - not working perfectly // diff --git a/core/lib/write_bundle.ts b/core/lib/write_bundle.ts index 6ef77233..6ba0997a 100644 --- a/core/lib/write_bundle.ts +++ b/core/lib/write_bundle.ts @@ -1,11 +1,11 @@ -import type { Component, Storage } from '../dts/factory.d.ts'; -import { lintignore, VnoPath } from '../utils/constants.ts'; -import { liveReloadScript } from '../utils/livereload.ts'; -import { hasValidInstance } from '../utils/type_guards.ts'; -import { fs } from '../utils/deps.ts'; +import type { Component, Storage } from "../dts/factory.d.ts"; +import { lintignore, VnoPath } from "../utils/constants.ts"; +import { liveReloadScript } from "../utils/livereload.ts"; +import { hasValidInstance } from "../utils/type_guards.ts"; +import { fs } from "../utils/deps.ts"; export function writeBundle(storage: Storage, isDev?: boolean): void { - // console.log('(/core/lib/write_bundle.ts) Storage: ', storage); + // console.log("(/core/lib/write_bundle.ts) Storage: ", storage); fs.ensureDirSync(VnoPath.Dir); fs.ensureDirSync(VnoPath.DirSSR); @@ -17,19 +17,22 @@ export function writeBundle(storage: Storage, isDev?: boolean): void { Deno.removeSync(VnoPath.StyleJS); } //"vno-build/build.js" -> dep: "import Vue from ", -> - + const reloadScript = liveReloadScript.replace( + ":8080", + `:${storage.config.options?.reloadPort}`, + ); // isDev => live reload Deno.writeTextFileSync( VnoPath.Build, lintignore + `${storage.vue.dep}"${storage.vue.cdn}";\n\n - ${isDev ? liveReloadScript : ''} ` + ${isDev ? reloadScript : ""} `, ); //vno-ssr/build.js Deno.writeTextFileSync( VnoPath.BuildSSR, - lintignore + `${storage.vue.dep}"https://deno.land/x/vue_js@/mod.js";\n` + lintignore + `${storage.vue.dep}"https://deno.land/x/vue_js@/mod.js";\n`, ); postorderTraverse(storage.root); @@ -43,10 +46,10 @@ export function writeBundle(storage: Storage, isDev?: boolean): void { Deno.writeTextFileSync( VnoPath.BuildSSR, - 'export default ' + storage.root.label, + "export default " + storage.root.label, { append: true, - } + }, ); } diff --git a/core/ssg/dev.ts b/core/ssg/dev.ts index eb864dc7..020da3f0 100644 --- a/core/ssg/dev.ts +++ b/core/ssg/dev.ts @@ -1,10 +1,10 @@ import { WebSocketClient, WebSocketServer, -} from "https://deno.land/x/websocket@v0.1.2/mod.ts"; -import { Application, send } from "https://deno.land/x/oak@v7.7.0/mod.ts"; -import { EventEmitter } from "https://deno.land/std@0.100.0/node/events.ts"; -import * as path from "https://deno.land/std@0.99.0/path/mod.ts"; +} from "https://deno.land/x/websocket@v0.1.3/mod.ts"; +import { Application, send } from "https://deno.land/x/oak@v10.0.0/mod.ts"; +import { EventEmitter } from "https://deno.land/std@0.117.0/node/events.ts"; +import * as path from "https://deno.land/std@0.117.0/path/mod.ts"; import { debounce } from "./utils.ts"; import { generate } from "./generate.ts"; diff --git a/core/utils/deps.ts b/core/utils/deps.ts index be4b2476..c957dce7 100644 --- a/core/utils/deps.ts +++ b/core/utils/deps.ts @@ -1,17 +1,17 @@ // deno std library -export * as fs from "https://deno.land/std@0.83.0/fs/mod.ts"; -export * as path from "https://deno.land/std@0.83.0/path/mod.ts"; -export * as colors from "https://deno.land/std@0.83.0/fmt/colors.ts"; -export * as http from "https://deno.land/std@0.83.0/http/mod.ts"; -export { v4 } from "https://deno.land/std@0.88.0/uuid/mod.ts"; //uuid generator +export * as fs from "https://deno.land/std@0.117.0/fs/mod.ts"; +export * as path from "https://deno.land/std@0.117.0/path/mod.ts"; +export * as colors from "https://deno.land/std@0.117.0/fmt/colors.ts"; +export * as http from "https://deno.land/std@0.117.0/http/mod.ts"; +export { v4 } from "https://deno.land/std@0.117.0/uuid/mod.ts"; //uuid generator export { assertEquals, assertNotEquals, -} from "https://deno.land/std@0.83.0/testing/asserts.ts"; // testing library +} from "https://deno.land/std@0.117.0/testing/asserts.ts"; // testing library import { WebSocketClient, WebSocketServer, -} from "https://deno.land/x/websocket@v0.1.1/mod.ts"; +} from "https://deno.land/x/websocket@v0.1.3/mod.ts"; export { WebSocketServer }; export type { WebSocketClient }; @@ -21,11 +21,12 @@ export { Context, Router, send, -} from "https://deno.land/x/oak@v6.5.0/mod.ts"; -export { superoak } from "https://deno.land/x/superoak@4.0.0/mod.ts"; // testing lib for oak +} from "https://deno.land/x/oak@v10.0.0/mod.ts"; +export { superoak } from "https://deno.land/x/superoak@4.5.0/mod.ts"; // testing lib for oak // third-party -import _ from "https://cdn.skypack.dev/lodash"; // lodash +import * as _ from "https://deno.land/x/lodash@4.17.15-es/lodash.js"; // lodash + import ProgressBar from "https://deno.land/x/progress@v1.2.3/mod.ts"; import { exec } from "https://deno.land/x/exec/mod.ts"; export { _, exec, ProgressBar }; @@ -35,5 +36,5 @@ export { compile as scssCompiler } from "https://raw.githubusercontent.com/crewd export * as sfcCompiler from "https://denopkg.com/crewdevio/vue-deno-compiler/mod.ts"; //event emitter for live reload -import { EventEmitter } from "https://deno.land/std@0.93.0/node/events.ts"; +import { EventEmitter } from "https://deno.land/std@0.117.0/node/events.ts"; export { EventEmitter };