Skip to content

Preconfigured webpack scaffold project with example theming with css-variables.

Notifications You must be signed in to change notification settings

Xesenix/webpack-scaffold

Repository files navigation

Build Status Appveyor Windows Build Status Coverage Status Known Vulnerabilities Dependencies Status

Required node version >= 8.0.0

Webpack 3 scaffold project

Demo application

DEMO

Check live demo of running this scaffold.

About

This is basic starting point for application using webpack v3 with some default configuration setup to properly load assets from different locations.

Workflow

It's work in progress but you can use those processes:

For development with HMR

  • Run npm run [appName]:build:dev this will copy vendor assets to local folder where from they can be served (if some assets are missing during development run this)
  • Run npm run [appName]:serve:dev this will start webpack-dev-server if some assets won't appear you probably need to add them to package.apps.[appName].assets

For production build:

  • Run npm run [appName]:build:prod this will build project and move all assets to package.apps.[appName].outPath path
  • Run npm [appName]:start to test build in browser localhost:8080

If you want run tests:

  • Run npm run [appName]:tdd for watch mode testing
  • Run npm run [appName]:test for single run

If you want analyze build size and dependencies use:

  • Run npm run [appName]:analyze

Extracting segments for translation:

  • Run npm run [appName]:xi18n this will extract all occurrences of __(...) into src/locales/messages.pot you can modify that behavior in scripts/extract.ts

Features

  • setting up build specific environmental variables
  • SASS (Bootstrap, Font Awesome)
  • HMR for stylesheets
  • loading png, jpg, gif, svg assets from local project paths and node_modules
  • loading eot, svg, ttf, woff, woff2 fonts from local project paths and node_modules
  • testing karma, jasmine, enzyme
  • Test coverage for typescript, javascript, react components
  • Typescript
  • simple theming with css variables
  • markdown loader
  • translating and extracting text segments to pot file
  • dependency injection via inversify

TODO

This project is using webpack v3 and probably has a lot place for improvement like:

  • find a way to avoid need for using $srcRoot variable in stylesheet (without copying every asset)
  • auto detect assets included in html template (this is problem if you override default behavior of copying to production all assets)
  • handle lazy loading of modules
  • use react router
  • use SVG Sprite loader or react-svg-loader

Documentation

xes-webpack-core

This project uses xes-webpack-core as base for webpack configuration so see it for details how you can setup project via package.json

Additional environmental configuration via .env file

If you need to add any secret configuration to your project you can use similar process of replacing source code as above with variables provided in .env file. For example:

file: .env

SOME_SECRET=secret value

and then anywhere in javascript you can use it like this:

file: src/some/script/path/script.js

const secret = process.env.SOME_SECRET;

.env file should be excluded from you repository via .gitignore.

Examples

Example stylesheet assets loading

Loading assets from stylesheet depends on entry point stylesheet used to generate url for that asset. So if you use as entry point stylesheet that is one folder deep relative to your package.apps.[appName].rootDir you need to compensate that path. So you can for example use structure like this:

for example:

file: package.json

{
  "apps": {
    "app": {
      "rootDir": "src",
      "styles": ["styles/subdir/entry-stylesheet.scss"]
    }
  }
}

so for entry point stylesheet we have 2 level deep entry point styles/subdir/ so then for:

file: src/styles/subdir/entry-stylesheet.scss

/**
 * For setting up assets paths for imported style sheets 
 * this file lays two directories under src folder
 */
$srcRoot: '../../' !default;
/* We import any other stylesheet that uses $srcRoot after setting up $srcRoot */
@import 'some/other/path/stylesheet';

.some-selector {
  /* Use this kind of path interpolation for getting image preview in Visual Code */
  background-image: url(#{$srcRoot + 'assets/path/to/img/a.png'});
}

file: src/styles/some/other/path/stylesheet.scss

/**
 * If this stylesheet would be entry point it would use that default setting
 * this stylesheet lies 4 directories deep relative to src folder
 */
$srcRoot: '../../../../' !default;

.some-other-selector {
  /* Use this kind of path interpolation for getting image preview in Visual Code */
  background-image: url(#{$srcRoot + 'assets/path/to/img/b.png'});
}

Example template referenced assets loading

For asset referenced in index.html we need to put all referenced assets into package.apps.[appName].assets param.

So for example if you have:

file: src/index.html

<html>
  <head>
    <link rel="icon" href="assets/path/to/image.png">
  </head>
  <body>
    <img src="assets/path/to/svg.svg"/>
  </body>
</html>

You need to setup something like this:

file: package.json

{
  "apps": {
    "app": {
      "root": "src",
      "template": "index.html",
      "assets": [
        "assets/path/to/image.png",
        "assets/path/to/svg.svg"
      ],
    }
  }
}

Example translation

You can use methods provided by lib/localize.ts for setting up current language and translating text segment like this:

import { __ } from 'lib/localize.ts';

console.log(__('text for translation'));

You can extract each occurrence of __(...) by calling:

npm run xi18n

that will result in extracting ${package.apps.[appName].rootDir}/${package.apps.[appName].localesDir}/messages.pot file that can be translated. After providing translated versions like:

  • ${package.apps.[appName].rootDir}/${package.apps.[appName].localesDir}/messages.pl.po
  • ${package.apps.[appName].rootDir}/${package.apps.[appName].localesDir}/messages.en.po

And after setting used languages in:

package.json

{
  "apps": {
    "[appName]": {
      "languages": ["en", "pl"]
    }
  }
}

they will be loaded and available to choose via:

import { setLocale } from 'lib/localize.ts';

setLocale('pl');

Resources

Some additional resources that can clarify concepts behind this scaffold project.

Localization

I am aiming to have each translations as separate file loaded at runtime so I don't have to build project for each language.

Testing

Project management related resources

Research

PurifyCSS

It would be nice to use PurifyCSS but webpack plugin for it is broken it doesn't run after assets are created. So, there is no index.html that can be used as entry point for purification purpose.

Dependency injection InversifyJS

Decorators for js and typescritpt differ from each other so we need to use inversify-vanillajs-helpers. At time of checking it out it unfortunately duplicates dependency on inversify increasing build size see reported issue.