Skip to content

Commit

Permalink
chore(docs): add global lib docs
Browse files Browse the repository at this point in the history
  • Loading branch information
filipesilva committed Aug 20, 2016
1 parent 2b7f8c4 commit 1a5b86d
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 28 deletions.
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ The generated project has dependencies that require **Node 4 or greater**.
* [Global styles](#global-styles)
* [CSS preprocessor integration](#css-preprocessor-integration)
* [3rd Party Library Installation](#3rd-party-library-installation)
* [Global Library Installation](#global-library-installation)
* [Updating angular-cli](#updating-angular-cli)
* [Known Issues](#known-issues)
* [Development Hints for hacking on angular-cli](#development-hints-for-hacking-on-angular-cli)
Expand Down Expand Up @@ -250,6 +251,8 @@ The `styles.css` file allows users to add global styles and supports
If the project is created with the `--style=sass` option, this will be a `.sass`
file instead, and the same applies to `scss/less/styl`.

You can add more global styles via the `apps[0].styles` property in `angular-cli.json`.

### CSS Preprocessor integration

Angular-CLI supports all major CSS preprocessors:
Expand Down Expand Up @@ -296,6 +299,42 @@ npm install moment --save
npm install @types/moment --save-dev
```

### Global Library Installation

Some javascript libraries need to be added to the global scope, and loaded as if
they were in a script tag. We can do this using the `apps[0].scripts` and
`apps[0].styles` properties of `angular-cli.json`.

As an example, to use [Boostrap 4](http://v4-alpha.getbootstrap.com/) this is
what you need to do:

First install Bootstrap from `npm`:

```bash
npm install bootstrap@next
```

Then add the needed script files to to `apps[0].scripts`.

```
"scripts": [
"../node_modules/jquery/dist/jquery.js",
"../node_modules/tether/dist/js/tether.js",
"../node_modules/bootstrap/dist/js/bootstrap.js"
],
```

Finally add the Bootstrap CSS to the `apps[0].styles` array:
```
"styles": [
"styles.css",
"../node_modules/bootstrap/dist/css/bootstrap.css"
],
```

Restart `ng serve` if you're running it, and Bootstrap 4 should be working on
your app.

### Updating angular-cli

To update `angular-cli` to a new version, you must update both the global package and your project's local package.
Expand Down
5 changes: 4 additions & 1 deletion addon/ng2/blueprints/ng2/files/angular-cli.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
"tsconfig": "tsconfig.json",
"prefix": "<%= prefix %>",
"mobile": <%= isMobile %>,
"styles": "styles.<%= styleExt %>",
"styles": [
"styles.<%= styleExt %>"
],
"scripts": [],
"environments": {
"source": "environments/environment.ts",
"prod": "environments/environment.prod.ts",
Expand Down
22 changes: 18 additions & 4 deletions addon/ng2/models/webpack-build-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,26 @@ export function getWebpackCommonConfig(projectRoot: string, environment: string,

const appRoot = path.resolve(projectRoot, appConfig.root);
const appMain = path.resolve(appRoot, appConfig.main);
const styles = path.resolve(appRoot, appConfig.styles);
const styles = appConfig.styles.map(style => path.resolve(appRoot, style));
const scripts = appConfig.scripts.map(script => path.resolve(appRoot, script));
const lazyModules = findLazyModules(appRoot);

let entry = {
main: [appMain]
};

// Only add styles/scripts if there's actually entries there
if (appConfig.styles.length > 0) entry.styles = styles;
if (appConfig.scripts.length > 0) entry.scripts = scripts;

return {
devtool: 'source-map',
resolve: {
extensions: ['', '.ts', '.js'],
root: appRoot
},
context: path.resolve(__dirname, './'),
entry: {
main: [appMain, styles]
},
entry: entry,
output: {
path: path.resolve(projectRoot, appConfig.outDir),
filename: '[name].bundle.js'
Expand Down Expand Up @@ -66,6 +73,9 @@ export function getWebpackCommonConfig(projectRoot: string, environment: string,
       { include: styles, test: /\.less$/, loaders: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader'] },
       { include: styles, test: /\.scss$|\.sass$/, loaders: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'] },

// load global scripts using script-loader
{ include: scripts, test: /\.js$/, loader: 'script-loader' },

       { test: /\.json$/, loader: 'json-loader' },
       { test: /\.(jpg|png)$/, loader: 'url-loader?limit=10000' },
       { test: /\.html$/, loader: 'raw-loader' },
Expand All @@ -90,6 +100,10 @@ export function getWebpackCommonConfig(projectRoot: string, environment: string,
.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")),
path.resolve(appRoot, appConfig.environments[environment])
),
new webpack.optimize.CommonsChunkPlugin({
// Optimizing ensures loading order in index.html
name: ['styles', 'scripts', 'main'].reverse();
}),
new webpack.optimize.CommonsChunkPlugin({
minChunks: Infinity,
name: 'inline',
Expand Down
30 changes: 11 additions & 19 deletions lib/config/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,27 +49,19 @@
"mobile": {
"type": "boolean"
},
"additionalEntries": {
"description": "Additional files to be included in the build.",
"styles": {
"description": "Global styles to be included in the build.",
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"properties": {
"input": {
"type": "string"
},
"output": {
"type": "string"
}
},
"additionalProperties": false
}
]
"type": "string"
},
"additionalProperties": false
},
"scripts": {
"description": "Global scripts to be included in the build.",
"type": "array",
"items": {
"type": "string"
},
"additionalProperties": false
},
Expand Down
54 changes: 50 additions & 4 deletions tests/e2e/e2e_workflow.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ describe('Basic end-to-end Workflow', function () {
expect(indexHtml).to.include('main.bundle.js');
});

it('styles.css is added to main bundle', function() {
it('styles.css is added to styles bundle', function() {
this.timeout(420000);

let stylesPath = path.join(process.cwd(), 'src', 'styles.css');
Expand All @@ -495,10 +495,10 @@ describe('Basic end-to-end Workflow', function () {

sh.exec(`${ngBin} build`);

var mainBundlePath = path.join(process.cwd(), 'dist', 'main.bundle.js');
var mainBundleContent = fs.readFileSync(mainBundlePath, { encoding: 'utf8' });
var stylesBundlePath = path.join(process.cwd(), 'dist', 'styles.bundle.js');
var stylesBundleContent = fs.readFileSync(stylesBundlePath, { encoding: 'utf8' });

expect(mainBundleContent.includes(testStyle)).to.be.equal(true);
expect(stylesBundleContent.includes(testStyle)).to.be.equal(true);
});

it('styles.css supports css imports', function() {
Expand All @@ -520,6 +520,52 @@ describe('Basic end-to-end Workflow', function () {
expect(mainBundleContent.includes(testStyle)).to.be.equal(true);
});

it('build supports global styles and scripts', function() {
this.timeout(420000);

sh.exec('npm install bootstrap@next', { silent: true });

const configFile = path.join(process.cwd(), 'angular-cli.json');
let configContent = fs.readFileSync(configFile, { encoding: 'utf8' });
configContent.replace('\"styles.css\"', `
"styles.css",
"../node_modules/bootstrap/dist/css/bootstrap.css"
`);

configContent.replace('\"scripts\": [],',`
"scripts": [
"../node_modules/jquery/dist/jquery.js",
"../node_modules/tether/dist/js/tether.js",
"../node_modules/bootstrap/dist/js/bootstrap.js"
],
`);

fs.writeFileSync(configFile, configContent, 'utf8');

sh.exec(`${ngBin} build`);

// checking for strings that are part of the included files
const stylesBundlePath = path.join(process.cwd(), 'dist', 'styles.bundle.js');
const stylesBundleContent = fs.readFileSync(stylesBundlePath, { encoding: 'utf8' });
expect(stylesBundleContent.includes('* Bootstrap ')).to.be.equal(true);

const scriptsBundlePath = path.join(process.cwd(), 'dist', 'styles.bundle.js');
const scriptsBundleContent = fs.readFileSync(scriptsBundlePath, { encoding: 'utf8' });
expect(scriptsBundleContent.includes('* jQuery JavaScript')).to.be.equal(true);
expect(scriptsBundleContent.includes('/*! tether ')).to.be.equal(true);
expect(scriptsBundleContent.includes('* Bootstrap ')).to.be.equal(true);
});

it('loads inline, styles, scripts and main in that order', function() {
const indexPath = path.join(process.cwd(), 'dist', 'index.html');
const indexContent = fs.readFileSync(indexPath, { encoding: 'utf8' });
let scriptTags = '<script type="text/javascript" src="inline.js"></script>' +
'<script type="text/javascript" src="styles.bundle.js"></script>' +
'<script type="text/javascript" src="scripts.bundle.js">' +
'<script type="text/javascript" src="main.bundle.js"></script>'
expect(indexContent.includes(scriptTags)).to.be.equal(true);
});

it('Serve and run e2e tests on dev environment', function () {
this.timeout(240000);

Expand Down

0 comments on commit 1a5b86d

Please sign in to comment.