npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

template9

v1.0.0-alpha.19

Published

CLI that kinda help with frontend development

Downloads

7

Readme

template9

Gitter CLI tests npm version npm license

CLI that kinda help with frontend development

Table of Content

Installation

$ npm i -g template9

Commands

init

$ t9 init
    what is the name of the project? : string!
    what is the root of the project? : string = frontend
    use docker? : [ true, false ] = true
    install dependencies? : [ true, false ] = true
    add the first entry? : [ true, false ] = true
  if (add the first entry?) {
    what is the name of the entry? : string!
    What is the default language code for this entry? : string = en
  }

this will apply the following:

`C: ${root}/config/index.d.ts` // type def file
`C: ${root}/config/index.js` // global config
`C: ${root}/src/components` // frontend components
`C: ${root}/src/config/index.ts` // frontend config
`C: ${root}/src/entries` // the view layer (entry)
`C: ${root}/src/redux` // data layer
`C: ${root}/src/types/index.ts` // frontend types
`C: ${root}/src/types/template-types.ts` // a readonly frontend types related to template9
`C: ${root}/types/index.ts` // global types
`C: ${root}/.editorconfig` // conventional configs for the editor
`C: ${root}/.gitignore` // paths to be ignored by git
`C: ${root}/package.json` // the npm package manifest
`C: ${root}/t9config.json` // template9 config file
`C: ${root}/tsconfig.json` // typescript config file
`C: ${root}/tslint.json` // typescript linting config
`C: ${root}/webpack.config.js` // webpack config file

if (add the first entry) {
  `C: ${root}/src/entries/${firstEntry}/components` // entry components
  `C: ${root}/src/entries/${firstEntry}/config/default-language/dictionary.json` // dictionary file
  `C: ${root}/src/entries/${firstEntry}/config/default-language/index.d.ts` // type def file
  `C: ${root}/src/entries/${firstEntry}/config/default-language/index.js` // default language config for this entry
  `C: ${root}/src/entries/${firstEntry}/config/index.ts` // entry config index file
  `C: ${root}/src/entries/${firstEntry}/entry/dictionary-fallbacks.json`
  `C: ${root}/src/entries/${firstEntry}/entry/dictionary-overwrites.json`
  `C: ${root}/src/entries/${firstEntry}/entry/dictionary.json`
  `C: ${root}/src/entries/${firstEntry}/entry/dictionary.scss.json`
  `C: ${root}/src/entries/${firstEntry}/entry/index.tsx`
  `C: ${root}/src/entries/${firstEntry}/entry/style-initial.scss`
  `C: ${root}/src/entries/${firstEntry}/entry/style-overwrite.scss`
  `C: ${root}/src/entries/${firstEntry}/entry/style.scss`
  `C: ${root}/src/entries/${firstEntry}/scenes` // entry scenes
  `C: ${root}/src/entries/${firstEntry}/types/index.ts` // entry types
  `C: ${root}/src/redux/${firstEntry}/actions/index.ts` // redux actions
  `C: ${root}/src/redux/${firstEntry}/constants/index.ts` // redux constants
  `C: ${root}/src/redux/${firstEntry}/constants/reducers.ts` // redux reducers
  `C: ${root}/src/redux/${firstEntry}/index.ts` // redux store entry point
}

add entry

$ t9 add entry
    what is the name of the entry? : string!
    What is the default language code for this entry? : string = "en"

this will do the following:

`C: ${root}/src/entries/${entry}/components`
`C: ${root}/src/entries/${entry}/config/default-language/dictionary.json`
`C: ${root}/src/entries/${entry}/config/default-language/index.d.ts`
`C: ${root}/src/entries/${entry}/config/default-language/index.js`
`C: ${root}/src/entries/${entry}/config/index.ts`
`C: ${root}/src/entries/${entry}/entry/dictionary-fallbacks.json`
`C: ${root}/src/entries/${entry}/entry/dictionary-overwrites.json`
`C: ${root}/src/entries/${entry}/entry/dictionary.json`
`C: ${root}/src/entries/${entry}/entry/dictionary.scss.json`
`C: ${root}/src/entries/${entry}/entry/index.tsx`
`C: ${root}/src/entries/${entry}/entry/style-initial.scss`
`C: ${root}/src/entries/${entry}/entry/style-overwrite.scss`
`C: ${root}/src/entries/${entry}/entry/style.scss`
`C: ${root}/src/entries/${entry}/scenes`
`C: ${root}/src/entries/${entry}/types/index.ts`
`C: ${root}/src/redux/${entry}/actions/index.ts`
`C: ${root}/src/redux/${entry}/constants/index.ts`
`C: ${root}/src/redux/${entry}/constants/reducers.ts`
`C: ${root}/src/redux/${entry}/index.ts`
`U: ${root}/t9config.json`

add config

$ t9 add config
    where do you want put the config? : [ "fullstack level", "frontend level", "entry level" ]
  if (where === "entry level" && t9config.entries.length > 1) {
    in what entry do you want put the config? : [ ...t9config.entries ]
  }
    what is the name of the config? : string!
  if (where !== "fullstack level") {
    typescript or javascript? : [ "typescript", "javascript" ] = "typescript"
  }

this will do the following:

if ("fullstack level"){
  `C: ${root}/config/${config}/dictionary.json`
  `C: ${root}/config/${config}/index.d.ts`
  `C: ${root}/config/${config}/index.js`
  `U: ${root}/config/index.ts`
} else if ("frontend level"){
  `C: ${root}/src/config/${config}/dictionary.json`
  if ("typescript"){
    `C: ${root}/src/config/${config}/index.ts`
  } else if ("javascript"){
    `C: ${root}/src/config/${config}/index.js`
    `C: ${root}/src/config/${config}/index.d.ts`
  }
  `U: ${root}/src/config/index.ts`
} else if ("entry level"){
  `C: ${root}/src/entries/${entry}/config/${config}/dictionary.json`
  if ("typescript"){
    `C: ${root}/src/entries/${entry}/config/${config}/index.ts`
  } else if ("javascript"){
    `C: ${root}/src/entries/${entry}/config/${config}/index.js`
    `C: ${root}/src/entries/${entry}/config/${config}/index.d.ts`
  }
  `U: ${root}/src/entries/${entry}/config/index.ts`
}
`U: ${root}/t9config.json`

add type

$ t9 add type
    where do you want put the type? : [ "fullstack level", "frontend level", "entry level" ]
  if (where === "entry level" && t9config.entries.length > 1) {
    in what entry do you want put the type? : [ ...t9config.entries ]
  }
    what is the name of the type? : string!
    add properties to the type
    enter an empty property name when done
  while (1) {
    property name : string!
    if (!property name) break;
    property type : [ "custom", ...t9.types ]
    if (!property type === "custom" ) {
      enter custom property type? : string!
    }
    required? : [ true, false ] = true
  }

this will do the following:

if ("fullstack level"){
  `U: ${root}/types/index.ts`
} else if ("frontend level"){
  `U: ${root}/src/types/index.ts`
} else if ("entry level"){
  `U: ${root}/src/entries/${entry}/types/index.ts`
}
`U: ${root}/t9config.json`

add scene

$ t9 add scene
    in what entry do you want put the scene? : [ ...t9config.entries ]
    under what scene do you want put it? : [ "root", ...t9config.scenes ]
    what is the name of the scene? : string!
    what is the url path of the scene? : string!
    preform exact match on the url path? : [ true, false] = true
    add properties to the scene
    enter an empty property name when done
  while (1) {
    property name : string!
    if (!property name) break;
    property type : [ "custom", ...t9.types ]
    if (!property type === "custom" ) {
      enter custom property type? : string!
    }
    nullable? : [ true, false ] = true
    undefinable? : [ true, false ] = false
    initial value? : { JS statement }
  }
    add lazy operation for this scene? : [ true, false ] = true
  if (add lazy operation for this scene) {
    what is the name of the operation? : string!
    repeatable? : [ true, false ] = false
    under what group do you want put its actions? : [ "/${scene?}", "root", ...t9config.actions.map(to groups), "< create new one >" ]
      if ( group === "< create new one >" ){
        what is the name of the group? : string!
      }
    add actions to the lazy operation
    enter an empty action name when done
    while (1) {
      action name : string!
      if (!action name) break;
    }
  }

this will do the following:

if (!scene){
  `C: ${root}/src/entries/${entry}/scenes/${name}/dictionary.json`
  `C: ${root}/src/entries/${entry}/scenes/${name}/index.tsx`
  `C: ${root}/src/entries/${entry}/scenes/${name}/index.scss`

  `U: ${root}/src/entries/${entry}/entry/index.scss`
  `U: ${root}/src/entries/${entry}/entry/index.tsx`
} else if (scene){
  `C: ${root}/src/entries/${entry}/scenes/${scene}/${name}/dictionary.json`
  `C: ${root}/src/entries/${entry}/scenes/${scene}/${name}/index.tsx`
  `C: ${root}/src/entries/${entry}/scenes/${scene}/${name}/index.scss`

  `U: ${root}/src/entries/${entry}/entry/index.scss`
  `U: ${root}/src/entries/${entry}/scenes/${scene}/index.tsx`
}
if ( add lazy operation for this scene ) {
  if (!group){
    `U: ${root}/src/redux/${entry}/actions/index.ts`
  } else if (group){
    `C|U: ${root}/src/redux/${entry}/actions/${group}/index.ts`
  }
}
`U: ${root}/t9config.json`

add component

$ t9 add component
    in what entry do you want put the component? : [ ...t9config.entries ]
    under what scene do you want put it? : [ "root", ...t9config.scenes ]
    what is the name of the component? : string!
    stateless? : [ true, false] = true
    add properties to the component
    enter an empty property name when done
  while (1) {
    property name : string!
    if (!property name) break;
    property type : [ "custom", ...t9.types ]
    if (!property type === "custom" ) {
      enter custom property type? : string!
    }
    nullable? : [ true, false ] = true
    undefinable? : [ true, false ] = false
  }
  if (!stateless) {
    fill the properties of the state object of the component
    enter an empty property name when done
  while (1) {
    property name : string!
    if (!property name) break;
    property type : [ "custom", ...t9.types ]
    if (!property type === "custom" ) {
      enter custom property type? : string!
    }
    nullable? : [ true, false ] = true
    undefinable? : [ true, false ] = false
    initial value? : { JS statement }
  }
  }

this will do the following:

if (!scene){
  `C: ${root}/src/entries/${entry}/components/${name}/dictionary.json`
  `C: ${root}/src/entries/${entry}/components/${name}/index.tsx`
  `C: ${root}/src/entries/${entry}/components/${name}/index.scss`

  `U: ${root}/src/entries/${entry}/entry/index.scss`
} else if (scene){
  `C: ${root}/src/entries/${entry}/scenes/${scene}/components/${name}/dictionary.json`
  `C: ${root}/src/entries/${entry}/scenes/${scene}/components/${name}/index.tsx`
  `C: ${root}/src/entries/${entry}/scenes/${scene}/components/${name}/index.scss`

  `U: ${root}/src/entries/${entry}/entry/index.scss`
}
`U: ${root}/t9config.json`

add lazy-operation

$ t9 add lazy-operation
    in what entry do you want put the operation? : [ ...t9config.entries ]
    under what scene do you want put it? : [ "root", ...t9config.scenes ]
    what is the name of the operation? : string!
    what is the url path of the operation? : string!
    preform exact match on the url path? : [ true, false] = true
    repeatable? : [ true, false ] = false
    under what group do you want put its actions? : [ "root", ...t9config.actions.map(to groups), "< create new one >" ]
      if ( group === "< create new one >" ){
        what is the name of the group? : string!
      }
    add actions to the operation
    enter an empty action name when done
    while (1) {
      action name : string!
      if (!action name) break;
    }

this will do the following:

if (!scene){
  `U: ${root}/src/entries/${entry}/entry/index.tsx`
} else if (scene){
  `U: ${root}/src/entries/${entry}/scenes/${scene}/index.tsx`
}
if (!group){
  `U: ${root}/src/redux/${entry}/actions/index.ts`
} else if (group){
  `C|U: ${root}/src/redux/${entry}/actions/${group}/index.ts`
}
`U: ${root}/t9config.json`

add action

$ t9 add action
    in what entry do you want put the action? : [ ...t9config.entries ]
    under what group do you want put it? : [ "root", ...t9config.actions.map(to groups), "< create new one >" ]
    if ( group === "< create new one >" ){
      what is the name of the group? : string!
    }
    what is the name of the action? : string!
    add parameter to the action function
    enter an empty parameter name when done
  while (1) {
    parameter name : string!
    if (!parameter name) break;
    parameter type : [ "custom", ...t9.types ]
    if (!parameter type === "custom" ) {
      enter custom parameter type? : string!
    }
    required? : [ true, false ] = true
    if ( !required ){
      default value? : string
    }
  }

this will do the following:

if (!group){
  `U: ${root}/src/redux/${entry}/actions/index.ts`
} else if (group){
  `C|U: ${root}/src/redux/${entry}/actions/${group}/index.ts`
}
`U: ${root}/t9config.json`

add reducer

$ t9 add reducer
    in what entry do you want put the reducer? : [ ...t9config.entries ]
    under what reducer do you want put it? : [ "root", ...t9config.reducers ]
    what is the name of the reducer? : string!
    fill the properties of the state object of the reducer
    enter an empty property name when done
  while (1) {
    property name : string!
    if (!property name) break;
    property type : [ "custom", ...t9.types ]
    if (!property type === "custom" ) {
      enter custom property type? : string!
    }
    nullable? : [ true, false ] = true
    undefinable? : [ true, false ] = false
    initial value? : { JS statement }
  }

this will do the following:

if (!reducer){
  `C: ${root}/src/redux/${entry}/reducer/${name}/index.ts`
  `U: ${root}/src/redux/${entry}/reducer/index.ts`
} else if (reducer){
  `C: ${root}/src/redux/${entry}/reducer/${reducer}/${name}/index.ts`
  `U: ${root}/src/redux/${entry}/reducer/${reducer}/index.ts`
}
`U: ${root}/t9config.json`

Flags

Version

$ t9 --version

or

$ t9 -v

Contributing

To get started see the contributing guidelines.

Unit test : Unit test are written in Mocha. Please add a unit test for every new feature or bug fix. npm test to run the test suite.

Documentation : Add documentation for every Command change. Feel free to send typo fixes and better docs!

Todos

CLI

  • [x] CLI prompts
  • [ ] Init a new project (with an optional example)
  • [ ] Update existing project (add scenes, ...etc)
  • [ ] Upgrade the template of an existing project

Template

  • [ ] Use the new React lazy and suspense for the lazy switch for scenes and sub-scenes
  • [ ] Lazy operations
  • [x] New Localization algorithm fc703dd
  • [x] Split style instead of loading one giant CSS bundle ee3d500
  • [ ] SSR with React.lazy (no need for server side Redux, just stick with loading lazy components with initial state )
  • [ ] Transition and animation
  • [ ] Blocking lazyloading
  • [ ] Use Concurrent React when it comes out instead of Blocking lazyloading

License

Copyright (c) 2019 Zakaria Mansouri (twitter: @zibanpirate) Licensed under the MIT license.