2.2.0 • Published 6 years ago

frontend-app v2.2.0

Weekly downloads
22
License
ISC
Repository
gitlab
Last release
6 years ago

frontend-app

Start using latest ES syntax and features, Livereload and Hot Module Replacement.

This includes babel-polyfill and whatwg-fetch polyfill and transpiles code using env and stage-0 Babel presets, so you may use many new features of the language out-of-the-box.

JSX and AngularJS dependency injection annotations (babel-plugin-ng-annotate, ng-annotate) are also supported.

Contents

Getting Started

one Make sure you have at least Node.js 6.13.1 and npm 5.2 installed:

node -v
npm -v

two Create package.json and install frontend-app:

mkdir my-app
cd my-app
npm init -y
npm install --save-dev frontend-app

three Install one of the examples, have your app entry point(s) in src directory and webpack.config.js in place. Then build using:

npm run build

Commands

init

Initialize example project.

npx frontend-app init <example-name>

Scripts

build

Files are transpiled, bundled and minified to the dist directory and are ready to be served. Source maps are also generated.

You may pass additional arguments to Webpack using --. For example, don't show progress information:

npm run build -- --progress false
dev

Bundle files to disk in watch mode (see Livereload).

dev-server

Bundle files in watch mode (see Dev Server).

Options

You may use package.json config field to set options. Example:

{
  "name": "my-app",
  "config": {
    "frontendApp": {
      "type": "react",
      "port": "8080",
      "devServer": {
        "port": "8081"
      }
    }
  }
}
type
  • react: Adds JSX support.
  • angular: Adds ng-annotate support.
  • all: Support JSX and ng-annotate. ng-strict-di is not supported in livereload mode.
  • slim (default): Just ES2015. No React or Angular specific transformations.
  • portlet: Sets output.publicPath in Spring MVC Liferay plugin project built with Maven. publicPath is determined by artifactId in pom.xml.

Multiple values are also supported. package.json config.frontendApp property example:

{
  "type": ["angular", "portlet"]
}
intl

Set "intl": "true" to use default list of available locales.

intl.locales

Available locales for Moment.js, React Intl and Intl. Default: ["fi", "sv", "en"] (When "intl": "true").

polyfills

Included polyfills. Default: ["babel-polyfill", "whatwg-fetch"]. Set "false" to not include any polyfills.

React Intl helper Components

Moved to @visma/react-intl-helpers.

List of Preconfigured Loaders

ExtensionLoader
JS
.js(ng-annotate-loader,) babel-loader
HTML
.htmlraw-loader
.hbshandlebars-template-loader
Styles
.csscss-loader
.scsssass-loader
.lessless-loader
Fonts & Media
.woff, .woff2url-loader
.ttfurl-loader
.eotfile-loader
.svgurl-loader
.pngurl-loader
.giffile-loader
.jpgfile-loader
Other
.txtraw-loader
.properties@visma/react-intl-helpers/cjs/loader

Livereload

Start build process, watch changes and refresh browser automatically on changes.

npm run dev

If you wish to serve files from different directory while developing (i.e. server content base is elsewhere):

npm run dev -- --output-path /some/other/content/base/dist

Dev Server

Use this for Hot Module Replacement with React or as an alternative to Livereload.

npm run dev-server

Single Entry (src/index.js)

my-app/
  dist/                                     // generated
    bundle.aa4915533a5b5f53c072.css
    bundle.aa4915533a5b5f53c072.css.map
    bundle.aa4915533a5b5f53c072.js
    bundle.aa4915533a5b5f53c072.js.map
  src/
    index.js                                // entry point
    other.js
  package.json
<link href="/dist/bundle.aa4915533a5b5f53c072.css" rel="stylesheet">
<script src="/dist/bundle.aa4915533a5b5f53c072.js"></script>

Multiple Entries (src/entries)

my-app/
  dist/                                     // generated
    commons.ee0ce0879c8b5aaefae4.css
    commons.ee0ce0879c8b5aaefae4.css.map
    commons.ee0ce0879c8b5aaefae4.js
    commons.ee0ce0879c8b5aaefae4.js.map
    entries/pageA/bundle.8036db3af1be1831e295.css
    entries/pageA/bundle.8036db3af1be1831e295.css.map
    entries/pageA/bundle.8036db3af1be1831e295.js
    entries/pageA/bundle.8036db3af1be1831e295.js.map
    entries/pageB/bundle.19596c286128bce14cf9.css
    entries/pageB/bundle.19596c286128bce14cf9.css.map
    entries/pageB/bundle.19596c286128bce14cf9.js
    entries/pageB/bundle.19596c286128bce14cf9.js.map
  src/
    entries/                                // entry points e.g. for each page
      pageA.js
      pageB.js
    other.js
  package.json

You must load commons bundle before the entry point. pageA.html:

<link href="/dist/commons.ee0ce0879c8b5aaefae4.css" rel="stylesheet">
<link href="/dist/entries/pageA/bundle.8036db3af1be1831e295.css" rel="stylesheet">
<script src="/dist/commons.ee0ce0879c8b5aaefae4.js"></script>
<script src="/dist/entries/pageA/bundle.8036db3af1be1831e295.js"></script>

Examples

React

one Install example project with React Router, React-Bootstrap, Bootstrap 3 custom build, React Intl and mock API:

npx frontend-app init react

two Start Webpack Dev Server:

npm run dev-server

three Go to http://localhost:8080/.

React (multiple entries)

one Install React example project for multi-portlet use, with Bootstrap 3 custom build, React Intl and mock API:

npx frontend-app init react-multiple-entries

two Start Webpack Dev Server:

npm run dev-server

three Go to http://localhost:8080/.

Angular

one Install example project with AngularUI Router and Bootstrap:

npx frontend-app init angular

two Start Webpack Dev Server:

npm run dev-server

three Go to http://localhost:8080/.

Webpack Configuration

Provide the built-in Webpack configuration. webpack.config.js:

module.exports = require("frontend-app/cjs/webpack/config").default;

Optionally merge own configuration. It will be merged into the built-in configuration using webpack-merge in smartStrategy mode:

module.exports = require("frontend-app/cjs/webpack/config").default.merge({
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: "babel-loader",
        include: join(process.cwd(), "node_modules/my-lib")
      }
    ]
  },
  output: {
    publicPath: "/dist/"
  }
});

And/or customize the final configuration:

module.exports = require("frontend-app/cjs/webpack/config")
  .default.merge({
    output: {
      publicPath: "/dist/"
    }
  })
  .customize(config => {
    // Edit entries.
    config.entry[2] = join(config.entry[2], "client");
    return config;
  });

Cookbook

History API Fallback with HTML Webpack Plugin

Suppose there is no backend or it's on another machine, and you just need to test some frontend code with Webpack Dev Server.

one Install dependencies:

npm install --save-dev html-webpack-plugin

two Edit webpack.config.js:

const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = require("frontend-app/cjs/webpack/config").default.merge({
  output: {
    publicPath: "/dist/"
  },
  devServer: {
    // Webpack Dev Server needs generated index.html in /dist directory for historyApiFallback to work.
    historyApiFallback: { index: "/dist/" }
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: "My App"
    })
  ]
});

CKEditor from /libs/ckeditor

one Install dependencies:

npm install --save-dev html-webpack-plugin html-webpack-template

two Edit webpack.config.js:

const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = require("frontend-app/cjs/webpack/config").default.merge({
  plugins: [
    new HtmlWebpackPlugin({
      inject: false,
      template: require("html-webpack-template"),
      scripts: ["/libs/ckeditor/ckeditor.js"],
      window: {
        CKEDITOR_BASEPATH: "/libs/ckeditor/"
      }
    })
  ]
});

three Use CKEDITOR in your app:

// CKEDITOR is available.
window.CKEDITOR;

CKEditor from node_modules

one Install dependencies:

npm install --save-dev html-webpack-plugin html-webpack-template ckeditor

two Edit webpack.config.js:

const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = require("frontend-app/cjs/webpack/config").default.merge({
  plugins: [
    new HtmlWebpackPlugin({
      inject: false,
      template: require("html-webpack-template"),
      window: {
        CKEDITOR_BASEPATH: "/node_modules/ckeditor/"
      }
    })
  ]
});

three Use CKEDITOR in your app:

import "ckeditor";

// CKEDITOR is available.
window.CKEDITOR;

Different output.publicPath in production

process.env.NODE_ENV is set correctly. You may use NODE_ENV, and for example process.env.npm_lifecycle_event to customize your configuration. webpack.config.js:

const production = process.env.NODE_ENV === "production";
// process.env.npm_lifecycle_event => "build" | "dev" | "dev-server"

module.exports = require("frontend-app/cjs/webpack/config").default.merge({
  output: {
    publicPath: production ? "/somepath/dist/" : "/dist/"
  }
});

Maven

one Install in webapp directory:

cd .../src/main/webapp
npm init
npm install --save-dev frontend-app

two Add build step to pom.xml:

<plugin>
    <groupId>com.github.eirslett</groupId>
    <artifactId>frontend-maven-plugin</artifactId>
    <version>1.0</version>
    <executions>
        <execution>
            <id>::install node and npm::</id>
            <goals>
                <goal>install-node-and-npm</goal>
            </goals>
        </execution>
        <execution>
            <id>::npm ci::</id>
            <goals>
                <goal>npm</goal>
            </goals>
            <configuration>
                <arguments>ci</arguments>
            </configuration>
        </execution>
        <execution>
            <id>::npm run build::</id>
            <goals>
                <goal>npm</goal>
            </goals>
            <configuration>
                <arguments>run build</arguments>
            </configuration>
        </execution>
    </executions>
    <configuration>
        <nodeVersion>v8.12.0</nodeVersion>
        <npmVersion>6.4.1</npmVersion>
        <workingDirectory>src/main/webapp</workingDirectory>
    </configuration>
</plugin>

three Add exclude rules to pom.xml:

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-war-plugin</artifactId>
	<configuration>
		<warSourceExcludes>src/,node/,node_modules/,package.json</warSourceExcludes>
		<webResources>
			<resource>
				<directory>src/main/webapp</directory>
				<filtering>false</filtering>
				<excludes>
					<exclude>src/**</exclude>
					<exclude>node/**</exclude>
					<exclude>node_modules/**</exclude>
					<exclude>package.json</exclude>
				</excludes>
			</resource>
		</webResources>
	</configuration>
</plugin>

.gitignore

/dist/
/node_modules/
2.2.0

6 years ago

2.1.0

6 years ago

2.0.0

6 years ago

2.0.0-rc.2

6 years ago

2.0.0-rc.1

6 years ago

2.0.0-beta.4

7 years ago

2.0.0-beta.3

7 years ago

1.2.0-beta.6

7 years ago

1.2.0-beta.5

7 years ago

2.0.0-beta.2

7 years ago

2.0.0-beta.1

7 years ago

2.0.0-beta.0

7 years ago

1.2.0-beta.4

7 years ago

1.2.0-beta.3

7 years ago

1.2.0-beta.2

7 years ago

1.2.0-1

7 years ago

1.2.0-0

7 years ago

1.1.0

7 years ago

1.0.0

7 years ago

0.8.1

7 years ago

0.8.0

7 years ago

0.7.1

8 years ago

0.7.0

8 years ago

0.6.4

8 years ago

0.6.3

8 years ago

0.6.2

8 years ago

0.6.1

8 years ago

0.6.0

8 years ago

0.5.1

8 years ago

0.5.0

8 years ago

0.4.10

8 years ago

0.4.9

8 years ago

0.4.8

8 years ago

0.4.7

8 years ago

0.4.6

8 years ago

0.4.5

8 years ago

0.4.4

8 years ago

0.4.3

8 years ago

0.4.2

8 years ago

0.4.1

8 years ago

0.4.0

8 years ago

0.3.1

8 years ago

0.3.0

8 years ago

0.2.7

8 years ago

0.2.6

8 years ago

0.2.5

8 years ago

0.2.4

8 years ago

0.2.2

8 years ago

0.2.1

8 years ago

0.2.0

8 years ago

0.1.4

8 years ago

0.1.3

8 years ago

0.1.2

8 years ago

0.1.1

8 years ago

0.1.0

8 years ago