Merge pull request #5455 from open-sausages/pulls/4.0/OSS-1691-update-docs

Update front-end build tooling docs
This commit is contained in:
Ingo Schommer 2016-05-05 20:25:57 +12:00
commit 9011aaefa7
7 changed files with 164 additions and 48 deletions

View File

@ -156,6 +156,11 @@ correctly configured form.
## JavaScript through jQuery.entwine
__Deprecated:__
The following documentation regarding Entwine applies to legacy code only.
If you're developing new functionality in React powered sections please refer to
[ReactJS in SilverStripe](./How_Tos/Extend_CMS_Interface.md#reactjs-in-silverstripe).
[jQuery.entwine](https://github.com/hafriedlander/jquery.entwine) is a thirdparty library
which allows us to attach behaviour to DOM elements in a flexible and structured mannger.
It replaces the `behaviour.js` library used in previous versions of the CMS interface.

View File

@ -2,6 +2,11 @@ title: Admin Layout
# CMS layout
__Deprecated:__
The following documentation regarding JavaScript layouts applies to legacy code only.
If you're developing new functionality in React powered sections please refer to
[ReactJS in SilverStripe](./How_Tos/Extend_CMS_Interface.md#reactjs-in-silverstripe).
The CMS markup is structured into "panels", which are the base units containing interface components (or other panels),
as declared by the class `cms-panel`. Panels can be made collapsible, and get the ability to be resized and aligned with
a layout manager, in our case [jLayout](http://www.bramstein.com/projects/jlayout/). This layout manager applies CSS

View File

@ -2,6 +2,11 @@
## Overview
__Deprecated:__
The following documentation regarding JavaScript layouts and Entwine applies to legacy code only.
If you're developing new functionality in React powered sections please refer to
[ReactJS in SilverStripe](./How_Tos/Extend_CMS_Interface.md#reactjs-in-silverstripe).
With the addition of side-by-side editing, the preview has the ability to appear
within the CMS window when editing content in the _Pages_ section of the CMS.
The site is rendered into an iframe. It will update itself whenever the content

View File

@ -6,6 +6,11 @@ summary: Advanced documentation about writing and customizing javascript within
The following document is an advanced guide on building rich javascript interactions within the SilverStripe CMS and
a list of our best practices for contributing and modifying the core javascript framework.
__Deprecated:__
The following documentation regarding jQuery, jQueryUI and Entwine applies to legacy code only.
If you're developing new functionality in React powered sections please refer to
[ReactJS in SilverStripe](./How_Tos/Extend_CMS_Interface.md#reactjs-in-silverstripe).
## jQuery, jQuery UI and jQuery.entwine: Our libraries of choice
We predominantly use [jQuery](http://jquery.com) as our abstraction library for DOM related programming, within the

View File

@ -62,6 +62,11 @@ Here we initialise the button based on the backend check, and assume that the bu
## Frontend support
__Deprecated:__
The following documentation regarding jQuery, jQueryUI and Entwine applies to legacy code only.
If you're developing new functionality in React powered sections please refer to
[ReactJS in SilverStripe](./Extend_CMS_Interface.md#reactjs-in-silverstripe).
As with the *Save* and *Save & publish* buttons, you might want to add some scripted reactions to user actions on the
frontend. You can affect the state of the button through the jQuery UI calls.

View File

@ -2,10 +2,15 @@ title: Customising the Admin Interface
summary: Extend the admin view to provide custom behavior or new features for CMS and admin users.
introduction: The Admin interface can be extended to provide additional functionality to users and custom interfaces for managing data.
The Admin interface is bundled within the SilverStripe Framework but is most commonly used in conjunction with the `CMS`
The Admin interface is bundled within the SilverStripe Framework but is most commonly used in conjunction with the `cms`
module. The main class for displaying the interface is a specialized [api:Controller] called [api:LeftAndMain], named
as it is designed around a left hand navigation and a main edit form.
Starting with SilverStripe 4, the user interface logic is transitioned from
jQuery and [jQuery.entwine](https://github.com/hafriedlander/jquery.entwine),
which is replaced with [ReactJS](http://reactjs.com/). The transition is
done iteratively, starting with `AssetAdmin` and `CampaignAdmin`.
[CHILDREN]
## How to's

View File

@ -263,97 +263,170 @@ Helpful hint: You can always edit your last commit message by using:
$ git commit --amend
## Working with client-side dependencies
## Client-side build tooling
From time to time client-side dependencies like jQuery need to be upgraded, added, or removed. We have some tools for dealing with that. Note this only applies to core SilverStripe dependencies, you're free to to manage dependencies in your project codebase however you like.
Core JavaScript, CSS, and thirdparty dependencies are managed with the build tooling
described below.
Note this only applies to core SilverStripe dependencies, you're free to manage
dependencies in your project codebase however you like.
### Node.js
The [Node.js](https://nodejs.org) JavaScript runtime is the foundation of our client-side build tool chain. If you want to do things like upgrade, add, or remove libraries, you'll need Node installed on your dev environment. Our build tooling supports the v4.2.x (LTS) version of Node.
The [Node.js](https://nodejs.org) JavaScript runtime is the foundation of our client-side
build tool chain. If you want to do things like upgrade dependencies, make changes to core
JavaScript or SCSS files, you'll need Node installed on your dev environment. Our build
tooling supports the v4.2.x (LTS) version of Node.
You'll likely want to manage multiple versions of Node, we suggest using
[Node Version Manager](https://github.com/creationix/nvm).
### npm
[npm](https://www.npmjs.com/) is the package manager we use for JavaScript libraries. It comes bundled with Node.js so should already have it installed if you have Node.
[npm](https://www.npmjs.com/) is the package manager we use for JavaScript dependencies.
It comes bundled with Node.js so should already have it installed if you have Node.
The configuration for an npm package goes in `package.json`. You'll see one in the root directory of `framework`. As well as being used for defining dependencies and basic package information, the `package.json` file has some handy scripts.
The configuration for an npm package goes in `package.json`. You'll see one in the root
directory of `framework`. As well as being used for defining dependencies and basic package
information, the `package.json` file has some other handy features.
#### npm scripts
The `script` property of a `package.json` file can be used to define command line scripts.
A nice thing about running commands from an npm script is binaries located in
`node_modules/.bin/` are temporally added to your `$PATH`. This means we can use dependencies
defined in `package.json` for things like compiling JavaScript and SCSS, and not require
developers to install these tools globally. This means builds are much more consistent
across development environments.
For more info on npm scripts see
[https://docs.npmjs.com/misc/scripts](https://docs.npmjs.com/misc/scripts)
To run an npm script, open up your terminal, change to the directory where `package.json`
is located, and run `$ npm run <SCRIPT_NAME>`. Where `<SCRIPT_NAME>` is the name of the
script you wish to run.
Here are the scripts which are available in `framework`
Note you'll need to run an `npm install` to download the dependencies required by these scripts.
##### build
```
$ npm run bundle
$ npm run build
```
`bundle` generates the lib and leftandmain JavaScript bundles.
Runs a Gulp task which builds the core JavaScript files. You will need to run this script
whenever you make changes to a JavaScript file.
Run this script with the `--development` flag to watch for changes in JavaScript files
and automatically trigger a rebuild.
##### lint
```
$ npm run thirdparty
$ npm run lint
```
`thirdparty` copies JavaScript files from the `node_modules` directory into the `thirdparty` directory. The `node_modules` directory is not part of source control, so you'll need to run this command if you have upgraded, or added a module.
Run `eslint` over JavaScript files reports errors.
```
$ npm run sanity
```
`sanity` makes sure files in `thirdparty` match files copied from `node_modules`. You should never commit custom changes to a library file. This script will catch them if you do :smile:
##### test
```
$ npm run test
```
This script runs the JavaScript unit tests.
Runs the JavaScript unit tests.
##### coverage
```
$ npm run coverage
```
This script generates a coverage report for the JavaScript unit tests. The report is generated in the `coverage` directory.
Generates a coverage report for the JavaScript unit tests. The report is generated
in the `coverage` directory.
##### css
```
$ npm run css
```
`css` will compile all of the .scss files into minified .css files. ProTip: run with the `--development` flag to compile non-minified css and watch for every time a .scss file is changed.
Compile all of the .scss files into minified .css files. Run with the `--development` flag to
compile non-minified CSS and watch for every time a .scss file is changed.
##### sprites
```
$ npm run sprites
```
`sprites` generates sprites from the individual image files in `admin/images/sprites/src`.
Generates sprites from the individual image files in `admin/images/sprites/src`.
##### thirdparty
```
$ npm run thirdparty
```
Copies legacy JavaScript dependencies from `node_modules` into the `thirdparty` directory.
This is only required legacy dependencies which are not written as CommonJS or ES6 modules.
All other modules will be included automatically with the `build` script.
##### sanity
```
$ npm run sanity
```
Makes sure files in `thirdparty` match files copied from `node_modules`. You should never commit
custom changes to a library file. This script will catch them if you do :smile:
##### lock
```
$ npm run lock
```
`lock` generates a "shrinkwrap" file containing all npm package versions and writes it to `npm-shrinkwrap.json`.
Run this command whenever a new package is added to `package.json`, or when updating packages.
Commit the resulting `npm-shrinkwrap.json`. This uses
a third party [npm-shrinkwrap](https://github.com/uber/npm-shrinkwrap) library
Generates a "shrinkwrap" file containing all npm package versions and writes it to
`npm-shrinkwrap.json`. Run this command whenever a new package is added to `package.json`,
or when updating packages. Commit the resulting `npm-shrinkwrap.json`. This uses a third party
[npm-shrinkwrap](https://github.com/uber/npm-shrinkwrap) library
since the built-in `npm shrinkwrap` (without a dash) has proven unreliable.
Of course to run these scripts, you'll need to get the dependencies, so run a `npm install` from the root directory to get started.
### Gulp
[Gulp](http://gulpjs.com/) is the build system which gets invoked when you run npm scripts in SilverStripe. All npm scripts have a corresponding Gulp task which you can find in `gulpfile.js`.
[Gulp](http://gulpjs.com/) is the build system which gets invoked by most npm scripts
in SilverStripe. The `gulpfile.js` script is where Gulp tasks are defined.
## Working with core JavaScript
Here are the Gulp tasks which are defined in `gulpfile.js`
Core JavaScript is managed by the same build tool chain as [client-side dependencies](#working-with-client-side-dependencies). Source file are located `javascript/src` directories, these are the files you should edit. Source files are input for the build tooling, which outputs distributions files, located in `javascript/dist` directories.
#### build
There are two parts of the build tooling which are important to understand when working with core JavaScript files.
This is where JavaScript files are compiled and bundled. There are two parts to this which
are important to understand when working core JavaScript files.
### Babel
##### Babel
[Babel](https://babeljs.io/) is a JavaScript compiler. It takes JavaScript files as input, performs some transformations, and outputs JavaScript files. In SilverStripe we use Babel to transform our JavaScript in two ways.
[Babel](https://babeljs.io/) is a JavaScript compiler. It takes JavaScript files as input,
performs some transformations, and outputs other JavaScript files. In SilverStripe we use
Babel to transform our JavaScript in two ways.
#### Transforming ES6
###### Transforming ES6
ECMAScript 6 (ES6) is the newest version of the ECMAScript standard. It has some great new features, but the browser support is still patchy, so we use Babel to transform ES6 source files back to ES5 files for distribution.
ECMAScript 6 (ES6) is the newest version of the ECMAScript standard. It has some great new
features, but the browser support is still patchy, so we use Babel to transform ES6 source
files back to ES5 files for distribution.
To see some of the new features check out [https://github.com/lukehoban/es6features](https://github.com/lukehoban/es6features)
To see some of the new features check out
[https://github.com/lukehoban/es6features](https://github.com/lukehoban/es6features)
#### Transforming to UMD
###### Transforming to UMD
[Universal Module Definition](https://github.com/umdjs/umd) (UMD) is a pattern for writing JavaScript modules. The advantage of UMD is modules can be 'required' by module loaders (AMD and ES6 / CommonJS) and can also be loaded via `<script>` tags. Here's a simple example.
[Universal Module Definition](https://github.com/umdjs/umd) (UMD) is a pattern for writing
JavaScript modules. The advantage of UMD is modules can be 'required' by module loaders
(AMD and ES6 / CommonJS) and can also be loaded via `<script>` tags. Here's a simple example.
```js
(function (global, factory) {
@ -372,15 +445,24 @@ To see some of the new features check out [https://github.com/lukehoban/es6featu
}));
```
The UMD wrapper is generated by Babel so you'll never have to write it manually, all you have to do is `npm run umd`.
The UMD wrapper is generated by Babel so you'll never have to write it manually,
it's handled for you by the build task.
### Browserify bundles
##### Browserify
One of the great new features of ES6 is [support for native modules](https://github.com/lukehoban/es6features#modules). In order to support modules, SilverStripe uses [Browserify](https://github.com/substack/node-browserify) to bundle modules for distribution.
One of the great new features in ES6 is
[support for native modules](https://github.com/lukehoban/es6features#modules).
In order to support modules, SilverStripe uses
[Browserify](https://github.com/substack/node-browserify) to bundle modules for distribution.
Browserify takes in entry file, creates an abstract syntax tree (AST) by recursively looking up all the `require` statements it finds, and outputs a bundled JavaScript file which can be executed in a browser.
Browserify takes an entry file, creates an abstract syntax tree (AST) by recursively
looking up all the `require` statements it finds, and outputs a bundled JavaScript file which
can be executed in a browser.
In addition to being a concatinated JavaScript file, Browserify bundles contain a lightweight `require()` implementation, and an API wrapper which allow modules to require each other. In most cases modules will require other modules from the same bundle. But it's also possible for bundled modules to require modules from other, external bundles.
In addition to being a concatenated JavaScript file, Browserify bundles contain a lightweight
`require()` implementation, and an API wrapper which allows modules to require each other at
runtime. In most cases modules will bundled together in one JavaScript file, but it's also
possible to require modules bundled in another file, these are called external dependencies.
In this example the `BetterField` module requires `jQuery` from another bundle.
@ -392,14 +474,14 @@ gulp.task('bundle-a', function () {
.transform(babelify.configure({
presets: ['es2015'] // Transform ES6 to ES5.
}))
.require('jQuery', { expose: 'jQuery' }) // Make jQuery available to other bundles.
.require('jQuery', { expose: 'jQuery' }) // Make jQuery available to other bundles at runtime.
.bundle()
.pipe(source('bundle-a.js'))
.pipe(gulp.dest('./dist'));
});
```
This generates a bundle which includes jQuery and makes it available to other bundles.
This generates a bundle `bundle-a.js` which includes jQuery and exposed it to other bundles.
__better-field.js__
@ -420,18 +502,22 @@ gulp.task('bundle-better-field', function () {
.transform(babelify.configure({
presets: ['es2015'] // Transform ES6 to ES5.
}))
.external('jQuery') // Get jQuery from another bundle.
.external('jQuery') // Get jQuery from another bundle at runtime.
.bundle()
.pipe(source('bundle-b.js'))
.pipe(gulp.dest('./dist'));
});
```
When Browserify bundles `./src/better-field.js` (the entry file) it will ignore all require statement that refer to 'jQuery' as assume it will be available via another bundle at runtime.
When Browserify bundles `./src/better-field.js` (the entry file) it will ignore all
require statements that refer to `jQuery` and assume `jQuery` will be available via another
bundle at runtime.
To transform and bundle core JavaScript `npm run build`. This will also watch for changes to source files and re-build automatically.
The advantage of using externals is a reduced file size. The browser only needs to download
`jQuery` once (inside `bundle-a.js`) rather than it being included in multiple bundles.
For debugging you can generate a 'development' bundle which includes source maps with `npm run build --development`. Note this is for local development only and shouldn't be pushed up with a pull request.
Core dependencies are are bundled and exposed in the `bundle-lib.js` file. Most of the libraries
a CMS developer requires are available a externals in that bundle.
## Some gotchas