furtherjs

0.0.2 • Public • Published

Features

  • Support source maps (prod/dev)
  • Add support for debugging the server
  • Add support for Modern ES features
  • Mark unused features for removal (tree shake)
  • Critical path
  • Better treatment of errors and warnings
  • Identify unused modules
  • Identify outdated modules
  • Identify outdated npm/node
  • Support csurf (for CSRF / security)
  • Generate reports (with print screens, charts, history, etc)
  • Generate reports based on Lighthouse
  • Use Virtualized Lists
  • Always think on perf (keep verifying it)
  • Suporte (e gerar) GraphQL
  • Tests with testcafe https://github.com/DevExpress/testcafe
  • Decide which components should use with split coding
  • Lazy install (install modules only if/when used)
  • Cluster for multi-threaded executions
  • Optimize images
  • Image loader
  • Code spliting
  • Script lazy loading
  • Style lazy loading
  • Code coverage
  • Hot reload
  • Memcache
  • Multitread
  • Extractions
  • Add support for TypeScript
  • Add support for CoffeeScript
  • Add support for Vue.js
  • Add support for React (preact)
  • Add support for Angular
  • Add support for Less
  • Add support for Stylus
  • Add support for Sass
  • Add support for CSS
  • Add support for StyledElements
  • Add support to HAML
  • Add support to PUG
  • Add Support for Marko (web components)
  • Add support for Polymer
  • Add offline support (service workers)
  • Add manifest.json file
  • JS linters
  • CSS linters
  • Run tests
  • Observe file sizes
  • Observe color contrasts
  • Validate accessibility
  • Start a server for managing components
  • Start http server
  • Support Web Assembly

Installing

You can install and use furtherjs globally or locally.
Both ways have some advantages and disadvantages.

Keep in mind that furtherjs will install its own dependencies as it needs.
That means that it will only install react, if you use react in your projects, for example.

Globally

If you install furtherjs globally, you have as advantages:

  • A single place to hold all the installed dependencies for builing/bundling all your projects
  • All the dependencies in your project are used inside your project, not to build it
  • Less space in your HD for repeadedly installed dependencies.
  • If you have many projects (as in a microservice environment, for example), they all will share the same dependencies structure and versions. Update a dependency for on, and you have updated it for them all.

To do so:

  1. Install further.js globally:

npm install -g furtherjs

  1. Link it in your project:

You can run in your terminal

cd [your-project-dir]
npm link furtherjs

Or simply add this to your npm scripts:

"scripts": {
    "start": "npm link furtherjs > null && node index.js"
}

You do not need to have furtherjs as a direct dependency in your project.

Locally

You can install furtherjs locally, to run only in your project.
The advantages include:

  • Sometimes you don't have access for installing global modules
  • You may have different versions for different projects
  • For your build, you will only have one dependency
  • Dependencies are not shared, and may be different ones, in each project of yours ... which may also be a disadvatage in some cases.

Expected file structure

This is the structure for you to work.
Don't mind creating it...furtherjs will create it on the go, when and if, it needs to.

  • index.js: Used to start the further services
  • src
    • client
      • main
      • components
      • public
    • server
      • main
      • services
      • public
      • private
    • cli
      • main
      • modules
      • config

Where main is just the same as a component for client, the same as a service for server, and the same as a module for cli.
Any of those must have an index.js, and anything else you might need, like styles (for client) or extra js files. Use the public directory to store things that will be publicly available, like static files.
In server side, you may also have a private place to store your configuration files or keys. The same as config for the CLI.

/index.js

Your index.js in the rootpath of your projects will be responsible for starting your project.
When it is in development mode, it will start the http server, the watch service and linters, and may also start the debugging service for node.
When it is in production mode, it will only start the http server, but will also minify and optmize images by default.

In it, you will start your application like this:

const App = require('furtherjs').App
const AppInstance = new App()
 
AppInstance.start({})

Where options can be:

Option Type Description Default
name String A name for your app ""
fullname String A longer, full name for your app ""
description String A short description bout your app ""
outputPath String The output path for your bundled app "dist"
src String The source path of your bundled app "src"
client Object Enables client side technologies in your project null
server Object Enables client side technologies in your project null
cli* Object Enables CLI side technologies in your project null
debug Bool Enables debugging features false
mode String Can be 'dev' or 'prod' 'prod'
icon String Path for your project's icon null
development Object Options for development mode null
production Object Options for development mode null
custom Object Options to be passed along to third party tools, for customization null

Basically, all these settings are optional.

  • CLI is still to be done

Options for client

Option Type Description Default
prependFiles Array of Strings Files to be prepended, loaded before your bundle []
appendFiles Array of Strings Files to be appended, loaded after your bundle []

Read more about prependFiles and appendFiles in the section "Vendors / Dependencies / CDNs". You can use it to load, for example, files from a CDN.

Options for server

Option Type Description Default
port Number The port to start the HTTP Server. If false, no server will be started 9091
verbose Bool If true, enables the verbose mode false

Options for development

Option Type Description Default
optimize Bool Optimizes all the source code true
optmizeImages Bool Optimizes all the images false

Options for production

Option Type Description Default
sourceMaps Bool Enables source maps for production false

Full example

You can see below, an example with all the options:

const App = require('furtherjs').App
const AppInstance = new App()
 
AppInstance.start({
  name: 'A Further test',
  icon: './src/client/public/favicon.png', // optional
  mode: 'dev', // use prod or dev (default: prod)
  outputPath: 'dist', // default
  src: 'src', // default 'src'
  debug: true, // default false
  development: {
    optmizeImages: false, // default: false
    optimize: false // default: false
  },
  production: {
    sourceMaps: true // default: false
  },
  client: {
    // adds css or js files to be loaded in your html pages
    // settings from https://github.com/jharris4/html-webpack-include-assets-plugin
    prependFiles: [
      // will preload jquery
      'vendors/jquery.js',
      // will preload this file from a CDN, with the type of "css" and an ID attribute
      {
        path: 'https://fonts.googleapis.com/css?family=Material+Icons',
        type: 'css',
        attributes: { id: 'google-font' }
      }
    ],
    appendFiles: [
      // will load this after other scripts are loaded
      'https://code.jquery.com/ui/1.12.1/jquery-ui.min.js'
    ]
  },
  server: { // set false if you dont want to start an HTTP server
      port: 9091,
      // (default true) renders files from /client/
      // if false, will serve only the /server/main/, in which case, you
      // would have to start your own http server
      // (default is true)
      http: true,
  },
  custom: {
      esLint: { // optional
          rules: {
              quotes: 2
          }
      },
  }
})

Aliases

You can import from aliases to make it easier for you to find the directories:

  • Comps (or Components): The path for your client components
  • Main: The path for your main
  • Templates: Path for your templates (isomorphic)
  • Utils: Path for your utils/isomorphic libraries

Lazy loading vs bundled modules

To add a module to your bundle, simply import it using the ES module import:

// will look for the index.js file and add it to the bundle
// of the current component
import { something } from 'some-module/'

If you want to lazy load a module, use require, instead.

// Will lazy load
// being loaded only when required
// therefore, not added to your bundle (unless some other script has imported it)
const something = require('./some-module/')

If no other scripts are importing it, it will be loaded only when used for the first time.

React, Vue, TypeScript and Coffee Script

Simply save files using their respective extensions: .jsx, .vue, .ts(or tsx) or .coffee.

Yep...that's it.

Styles

To use css, less, sass or stylus, just save your files with their respective extensions: css, less, scss/sass or styl. Then import them anywhere.

If your style file is imported from a script that is lazy loaded, the style files will also be lazy loaded.

Linters

All CSS, HTML and JavaScript is going to be linted.
Period.
If you want to change the default linting settings, refer to the files created in .further directory, created in your project's root directory.

You can also send the settings using the custom property when initializing the service:

AppInstance.start({
  // ...
  custom: {
      // these are all optional
    esLint: {
      rules: {
        quotes: 2
      }
    }
  }
  // ...
})

Images

All images will be optmized using a list of optmization tools.
You can compare the original size to the resulting one from your src to your dist directories.

Sprites

You can save images in any directory called sprites and those images will be merged into one single image and loaded in your page with a respective CSS.

You can use any sprite position by the pattern icon-[image-file-name].
For example, if you have images with the names "save.png", "home.png" and "send.png", you will be able to use the classes icon-save, icon-home and icon-send.

Icons

If you specify an icon in your configuration, this icon will be used as your favicon, but will also be optimized to it.
Different platforms will use diferent icons and this is actually very annoying to configure, so, we do that for you!
It will generate about 40 different icons for production, and a few icons for your development environment.
These icons will be loaded appropriately in your html file.

Also, it will generate the icon files for the different sizes and types.

Source maps

We will generate sourcemaps for you, don't worry. They will be there.

Debugging

When you set the debug property to true in your configuration, it will start a debugging server/service for you.
This allows you to remote debug even your node application using breakpoints and everything else.

When you start it in debug mode you will be prompted to choose an option to either:

  • Do not copy: It will not do anything, but will still start the debugging server and service
  • Copy Chrome URL: Will add to your clipboard the Full URL for debugging your server. Just open a tab in your chrome browser, paste the url and hit enter.
  • Copy Socket URL: Sets into your clipboard the URL for the socket of your debugging service. This is used by third party tools (or your own tool) to listen for your debugging events.
  • Copy Chrome URL: Same as "Copy Chrome URL", but will not add it to your clipboard, instead, will only show you the url in the terminal.
  • Copy Socket URL: Same as "Copy Socket URL", but will not add it to your clipboard, instead, will only show you the url in the terminal.

Except for the first option, all the other options expect you to hit [ENTER] again in your terminal. This allows you to debug your application since its first moments starting the server, giving you time to open the external debugging tool.

If you are using Chrome, another interesting way to do that is by clicking the "Green Node Logo" that will appear in the top left of your DevTools.

Vendors / Dependencies / CDNs

Use this to load global libraries or other dependencies you don't want to be loaded in the bundle or embeded in your source, if you want to load files from CDNs or if you want to append or prepend files.
They will be added to be loaded in your HTML file.

These settings are used as described in the HTMLWebpackIncludeAssetsPlugin.

If you have the files you want to use, store them in src/client/public/vendors. The vendors directory here is optional, but it will help you organize things. To set it, add the prependFiles or appendFiles properties to your client configuration.

AppInstance.start({
  // ...
  client: {
    // list of your files to be loaded (both css or js)
    prependFiles: [], // will be added BEFORE other dependencies
    appendFiles: [] // will be added AFTER other dependencies
  }
  // ...
}

If you need to load a file that has not a valid extension (for example, when you load a font from google fonts), you can specify the file type. To do that, instead of passing a string, you will pass an object containing the path and the type. You can optionally pass an attributes as well.

For example let's say we want a jquery file to be loaded from our path src/client/public/vendors/jquery.js. This needs to be loaded before your files, as you want to use it. And also, we will load a JQueryUI from its CDN, and this one should be loaded after your main files.
We will also load some fonts from google fonts and give it an id.
In this case, we would have:

AppInstance.start({
  // ...
  client: {
    prependFiles: [
      'vendors/jquery.js'
      {
        path: 'https://fonts.googleapis.com/css?family=Material+Icons',
        type: 'css',
        attributes: { id: 'google-font'}
      }
    ],
    appendFiles: ['https://code.jquery.com/ui/1.12.1/jquery-ui.min.js']
  }
  // ...
}

Your CSS files will be added in the header, while your javaScripts will be added to the footer of your HTML file.

Starting as a static server

If you want to simply copy your client directory from your dist into a static server (like, let's say, when using gh-pages for example) you can do so.

Also, if you want to, you can install http-server and then run it to see the static page running in your browser, like so:

http-server ./dist/client -p [PORT]

There is a downside, though.
In order for us to have all the paths working we need to use a redirect from your root / path to your /main. You will notice that in your browser's address bar.

Starting only the http server with npm

When you start your project using node index.js, further.js will take care of it and will start your http-server for you, plus running some other useful things under the hood.

In case you want to start only the HTTP Server (also, without the redirect mentioned in the "static server" session) or if your server allows you to run node commands and you want to start only the http-server, you can optionally start it yourself.

node ./dist/server/

This will take care of your routes and start your HTTP server.

FAQ

  • ENOSPC

If you see this error, this might be because you don't have enought space in disk, or your watch configuration has a small limit by default.
If the second options is your case, you can fix it using the following command:

echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p

  • Stylelint Rules

The rules for stylelint follow the pattern documented at styleling rules.

  • Why is my build slow

Your first build will be a little slower, but subsequent builds should be much faster.
The first build gets slower when you have debugger enabled and is connecting to a remote debugging tool (such as chrome devtool, for example).

If you are using many different technologies in the same project, this might affect the build time. For example, if you have files in typescript, coffeescript, vanillajs, less, stylus, sass...all in the same project. Even though, it was not supposed to take more than a second or two for re-builds when watching.

We use some caching layers for your builds to be faster and reuse the most as possible.

If you are facing a problem related to it, please open an issue.

  • Rebuild node-sass

Sometimes, due to some environment change, node-sass may complay about it and require you to rebuild it.
To do so, simply run the command:

npm rebuild node-sass --force

Package Sidebar

Install

npm i furtherjs

Weekly Downloads

2

Version

0.0.2

License

MIT

Last publish

Collaborators

  • felipenmoura