├── .gitignore
├── test
├── mochats
│ ├── index.ts
│ ├── component.html
│ ├── example-component.html
│ ├── component.ts
│ └── component.spec.ts
├── mochajs
│ ├── index.js
│ ├── component.html
│ ├── style.scss
│ ├── example-component.html
│ ├── component.js
│ ├── example-component.js
│ ├── example-component.original.js
│ └── component.spec.js
├── karma
│ ├── example-component.html
│ ├── test-user.component.html
│ ├── test.component.html
│ ├── test-user.component.ts
│ ├── test.component.ts
│ ├── index.ts
│ └── test.component.spec.ts
└── hello
│ ├── hello.ts
│ └── test.ts
├── .editorconfig
├── tsconfig.json
├── rollup.config.js
├── .travis.yml
├── LICENSE
├── package.json
├── README.md
├── karma.conf.js
└── src
└── index.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | dist/
3 | .vscode
4 |
--------------------------------------------------------------------------------
/test/mochats/index.ts:
--------------------------------------------------------------------------------
1 | import './component.spec';
2 |
--------------------------------------------------------------------------------
/test/mochajs/index.js:
--------------------------------------------------------------------------------
1 | require('./component.spec.js');
2 |
--------------------------------------------------------------------------------
/test/mochajs/component.html:
--------------------------------------------------------------------------------
1 | component.html content loaded
2 |
--------------------------------------------------------------------------------
/test/mochats/component.html:
--------------------------------------------------------------------------------
1 | component.html content loaded
2 |
--------------------------------------------------------------------------------
/test/karma/example-component.html:
--------------------------------------------------------------------------------
1 | example-component.html content loaded
2 |
--------------------------------------------------------------------------------
/test/mochats/example-component.html:
--------------------------------------------------------------------------------
1 | example-component.html content loaded
2 |
--------------------------------------------------------------------------------
/test/karma/test-user.component.html:
--------------------------------------------------------------------------------
1 | test-user.component.html content loaded
2 |
--------------------------------------------------------------------------------
/test/karma/test.component.html:
--------------------------------------------------------------------------------
1 | test.component.html loaded
2 |
3 |
--------------------------------------------------------------------------------
/test/mochajs/style.scss:
--------------------------------------------------------------------------------
1 | $test: 150px;
2 | .test {
3 | width: $test;
4 | font-family: fantasy;
5 | }
6 |
--------------------------------------------------------------------------------
/test/hello/hello.ts:
--------------------------------------------------------------------------------
1 | export function hello() {
2 | return 'Hello World!';
3 | }
4 |
5 | export default hello;
6 |
--------------------------------------------------------------------------------
/test/mochajs/example-component.html:
--------------------------------------------------------------------------------
1 | blaah
2 |
3 | example-component !
4 |
5 |
6 | minfiy this
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/mochajs/component.js:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * @Component({
4 | * selector: 'component',
5 | * templateUrl: './component.html'
6 | * styleUrls: [
7 | * './style.scss'
8 | * ]
9 | * })
10 | */
11 |
12 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | end_of_line = lf
6 | insert_final_newline = true
7 | indent_style = space
8 | indent_size = 2
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
--------------------------------------------------------------------------------
/test/karma/test-user.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'test-user',
5 | templateUrl: './test-user.component.html'
6 | })
7 | export class TestUserComponent {
8 | constructor() {}
9 | }
10 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowJs": true,
4 | "module": "commonjs",
5 | "target": "es5",
6 | "noImplicitAny": false,
7 | "sourceMap": false,
8 | "removeComments": true
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/hello/test.ts:
--------------------------------------------------------------------------------
1 | import hello from './hello';
2 | import { expect } from 'chai';
3 |
4 | describe('Hello function', () => {
5 | it('should return hello world', () => {
6 | const result = hello();
7 | expect(result).to.equal('Hello World!');
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import buble from 'rollup-plugin-buble';
2 |
3 | var external = Object.keys(require('./package.json').dependencies).concat(['colors', ,'fs', 'path', 'replace']);
4 |
5 | export default {
6 | entry: 'src/index.js',
7 | plugins: [ buble() ],
8 | external: external,
9 | targets: [
10 | { dest: 'dist/rollup-plugin-angular.js', format: 'cjs' },
11 | { dest: 'dist/rollup-plugin-angular.esm.js', format: 'es' }
12 | ]
13 | };
14 |
--------------------------------------------------------------------------------
/test/mochats/component.ts:
--------------------------------------------------------------------------------
1 |
2 | import { Component } from '@angular/core';
3 | /**
4 | * @Component({
5 | * selector: 'example',
6 | * templateUrl: './example-component.html'
7 | * })
8 | * export class ExampleComponent {}
9 | * @export
10 | * @class ExampleComponent
11 | * @implements {AfterViewChecked}
12 | */
13 | @Component({
14 | selector: 'component',
15 | templateUrl: `./component.html`
16 | })
17 | export class TestComponent {
18 | constructor() {}
19 | }
20 |
--------------------------------------------------------------------------------
/test/karma/test.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | /**
3 | * @Component({
4 | * selector: 'example',
5 | * templateUrl: './do-not-load-this-component.html'
6 | * })
7 | * export class ExampleComponent {}
8 | * @export
9 | * @class ExampleComponent
10 | * @implements {AfterViewChecked}
11 | */
12 | @Component({
13 | selector: 'test',
14 | templateUrl: `./test.component.html`
15 | })
16 | export class TestComponent {
17 | constructor() {}
18 | }
19 |
--------------------------------------------------------------------------------
/test/karma/index.ts:
--------------------------------------------------------------------------------
1 | // import 'es6-shim';
2 | import 'reflect-metadata';
3 | import 'core-js/es6';
4 | import 'core-js/es7/reflect';
5 |
6 | // Typescript emit helpers polyfill
7 | // require('ts-helpers');
8 |
9 | import 'zone.js/dist/zone';
10 | import 'zone.js/dist/long-stack-trace-zone';
11 | import 'zone.js/dist/proxy';
12 | import 'zone.js/dist/sync-test';
13 | import 'zone.js/dist/jasmine-patch';
14 | import 'zone.js/dist/async-test';
15 | import 'zone.js/dist/fake-async-test';
16 |
17 | // RxJS
18 | import 'rxjs/Rx';
19 |
20 | import * as browser from '@angular/platform-browser-dynamic/testing';
21 | import * as testing from '@angular/core/testing';
22 |
23 | testing.TestBed.initTestEnvironment(
24 | browser.BrowserDynamicTestingModule,
25 | browser.platformBrowserDynamicTesting()
26 | );
27 | Error.stackTraceLimit = Infinity;
28 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 2000;
29 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js: '6'
3 | deploy:
4 | provider: npm
5 | email: felix@stkn.org
6 | api_key:
7 | secure: bU+7l8jBtPV7LAxN7NimbrSIEM+GvDU5CpVbq4T+ix3wzkYdaCaOLS60kJNoS/cB5sAAENZZRkyBLuwDJZ/u38IrVc3k2p6U/eu7i+5ErvHB6v6z4yB6yOiFqYbEloPWpvROX3KN2AQkot8TNl81HO2cTG0vHEipusXh8g/xIG/62gJvHXosDEySd7Wfmy0cDijZUD7UDbTm+INioToHvI5UdSq35JdBFblALP6eRBqE+WtW12Nql2/oDTtWblBLopFhXqptpJINAYZL3YclPRmGycfvhqN2ygjdEo6bltvdphTJU9QTua2XFrwer6dJI8bKDt4cmJUsTEbAVRMhjCWW4zGiRQx9C4GnhccH8+0mupvLdrkPEgvcwCUaHDyDAJ++UgC/b9PglrZUKP/ol6KdN2fCBmwf5zrNjygy0OYWPsiUrd1PiqDF3KkLMbOoymEUI7nNQ6oTJDu8L43GSuaysKUYUOafiPqoSFes144BZ/nlRpIiDjmdo1AhuzFDry9kuQYeHk6frEswY9aQ43NfDtzHygs35FPZ7MGtpNWbFTnp72MnJ6MdDE38zz8YparrkH/sX+JBHWVsmE5aYwuphtL4waeTqZRZq1S//dZLp7WSz2jd43h13A/h3ggkuIp4f8sw8FQtqmWZwehFnnYHw7+KR4+u2uuTrwtMaf4=
8 | on:
9 | tags: true
10 | repo: cebor/rollup-plugin-angular
11 | before_script:
12 | - "export DISPLAY=:99.0"
13 | - "sh -e /etc/init.d/xvfb start"
14 | - sleep 3 # give xvfb some time to start
15 |
--------------------------------------------------------------------------------
/test/mochajs/example-component.js:
--------------------------------------------------------------------------------
1 | /**
2 | ExampleComponent.decorators = [
3 | { type: Component, args: [{
4 | selector: 'example-component',
5 | templateUrl: `./example-component.html`,
6 | styleUrls: [
7 | './style.scss',
8 | './style.scss'
9 | ]
10 | },] },
11 | ];
12 |
13 | */
14 | ExampleComponent.decorators = [
15 | { type: Component, args: [{
16 | selector: 'example-component',
17 | templateUrl: `./example-component.html`,
18 | styleUrls: [
19 | './style.scss',
20 | './style.scss'
21 | ]
22 | },] },
23 | ];
24 |
25 | ExampleComponent.decorators = [
26 | { type: Component, args: [{
27 | selector: 'example-component',
28 | template: `blaaah`,
29 | style: [
30 | '.test{ }',
31 | '.test_aa {}'
32 | ]
33 | },] },
34 | ];
35 |
--------------------------------------------------------------------------------
/test/mochajs/example-component.original.js:
--------------------------------------------------------------------------------
1 | /**
2 | ExampleComponent.decorators = [
3 | { type: Component, args: [{
4 | selector: 'example-component',
5 | templateUrl: `./example-component.html`,
6 | styleUrls: [
7 | './style.scss',
8 | './style.scss'
9 | ]
10 | },] },
11 | ];
12 |
13 | */
14 | ExampleComponent.decorators = [
15 | { type: Component, args: [{
16 | selector: 'example-component',
17 | templateUrl: `./example-component.html`,
18 | styleUrls: [
19 | './style.scss',
20 | './style.scss'
21 | ]
22 | },] },
23 | ];
24 |
25 | ExampleComponent.decorators = [
26 | { type: Component, args: [{
27 | selector: 'example-component',
28 | template: `blaaah`,
29 | style: [
30 | '.test{ }',
31 | '.test_aa {}'
32 | ]
33 | },] },
34 | ];
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Felix Itzenplitz
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/test/mochats/component.spec.ts:
--------------------------------------------------------------------------------
1 |
2 | import { rollup } from 'rollup';
3 | import * as commonjs from 'rollup-plugin-commonjs';
4 | import * as nodeResolve from 'rollup-plugin-node-resolve';
5 | import * as typescript from 'rollup-plugin-typescript';
6 | import { expect, assert } from 'chai';
7 | import * as angular from '../../dist/rollup-plugin-angular.js';
8 | import * as colors from 'colors';
9 |
10 | process.chdir('test');
11 |
12 |
13 | const bundle = () => {
14 | return rollup({
15 | entry: 'mochats/component.ts',
16 | plugins: [
17 | angular(),
18 | commonjs(),
19 | typescript({
20 | typescript: require('./../../node_modules/typescript')
21 | })
22 | ]
23 | });
24 | }
25 |
26 | describe('rollup-plugin-angular', () => {
27 | console.info(`-------------------`);
28 | console.info(colors.blue(`start test mocha:ts`));
29 | console.info(`-------------------`);
30 | beforeEach(() => {
31 |
32 | });
33 | it('should not have example-component.html file content loaded from comment', () => {
34 | return bundle()
35 | .then(bundle => {
36 | return bundle
37 | .generate({ format: 'iife', moduleName: 'component' })
38 | .then(generated => {
39 | assert.ok(generated.code);
40 | expect(generated.code.includes(`example-component.html content loaded`)).to.equal(false);
41 | return generated;
42 | });
43 | });
44 | });
45 |
46 | it('should have component.html file content loaded', () => {
47 | return bundle()
48 | .then(bundle => {
49 | return bundle
50 | .generate({ format: 'iife', moduleName: 'component' })
51 | .then(generated => {
52 | assert.ok(generated.code);
53 | expect(generated.code.includes(`component.html content loaded`)).to.equal(true);
54 | return generated;
55 | });
56 | });
57 | });
58 | });
59 |
--------------------------------------------------------------------------------
/test/karma/test.component.spec.ts:
--------------------------------------------------------------------------------
1 |
2 | // external
3 | import { DebugElement, NO_ERRORS_SCHEMA, ViewChild } from '@angular/core';
4 | import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
5 | import { By } from '@angular/platform-browser';
6 | import { TestBed, async, inject, ComponentFixture } from '@angular/core/testing';
7 |
8 | // internal
9 | import { TestComponent } from './test.component';
10 | import { TestUserComponent } from './test-user.component';
11 |
12 | beforeAll(() => {
13 | TestBed.resetTestEnvironment();
14 | TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
15 | });
16 |
17 | describe('TestComponent', () => {
18 |
19 | let comp: TestComponent;
20 | let debugElement: DebugElement;
21 | let fixture: ComponentFixture;
22 | let nativeElement: HTMLElement;
23 |
24 | beforeEach(async(() => {
25 | TestBed.configureTestingModule({
26 | declarations: [
27 | TestComponent,
28 | TestUserComponent
29 | ]
30 | }).compileComponents();
31 | }));
32 |
33 | // synchronous beforeEach
34 | beforeEach(() => {
35 | fixture = TestBed.createComponent(TestComponent);
36 |
37 | // get from fixture
38 | comp = fixture.componentInstance;
39 | nativeElement = fixture.nativeElement;
40 | debugElement = fixture.debugElement;
41 | });
42 |
43 | it('should be defined', async(() => {
44 | expect(fixture).toBeDefined();
45 | expect(comp).toBeTruthy();
46 | console.info(fixture.componentRef);
47 | }));
48 | it('should have test.component.html loaded', async(() => {
49 | expect(nativeElement.textContent).toContain('test.component.html loaded');
50 | }));
51 | it('should have test.component.html loaded', async(() => {
52 | expect(nativeElement.textContent).toContain('test-user.component.html content loaded');
53 | }));
54 | });
55 |
--------------------------------------------------------------------------------
/test/mochajs/component.spec.js:
--------------------------------------------------------------------------------
1 | const { rollup } = require('rollup');
2 | const assert = require('chai').assert;
3 | const expect = require('chai').expect;
4 | const angular = require('../../dist/rollup-plugin-angular.js');
5 | const external = Object.keys(require('./../../package.json').dependencies).concat(['fs', 'path']);
6 | const colors = require('colors');
7 | const sass = require('node-sass');
8 | const cleanCSS = require('clean-css');
9 | const htmlMinifier = require('html-minifier');
10 | const cssmin = new cleanCSS();
11 | const htmlminOpts = {
12 | caseSensitive: true,
13 | collapseWhitespace: true,
14 | removeComments: true
15 | };
16 |
17 | process.chdir('test');
18 |
19 | describe('rollup-plugin-angular', () => {
20 | console.info(`-------------------`);
21 | console.info(colors.blue(`start test mocha:js`));
22 | console.info(`-------------------`);
23 | it('should not have component.html file content loaded from comment', () => {
24 | return rollup({
25 | input: 'mochajs/component.js',
26 | external: external,
27 | plugins: [
28 | angular({
29 | replace: false
30 | })
31 | ]
32 | })
33 | .then(bundle => {
34 | return bundle
35 | .generate({
36 | format: 'umd',
37 | name: 'component'
38 | })
39 | .then(generated => {
40 | expect(generated.code.includes(`component.html content loaded`)).to.equal(false);
41 | assert.ok(generated.code);
42 | });
43 | });
44 | });
45 |
46 | it('should have example-component.html file content loaded', () => {
47 | return rollup({
48 | input: 'mochajs/example-component.js',
49 | external: external,
50 | plugins: [
51 | angular({
52 | preprocessors: {
53 | template: template => htmlMinifier.minify(template, htmlminOpts),
54 | style: scss => {
55 | const css = sass.renderSync({ data: scss }).css;
56 | return cssmin.minify(css).styles;
57 | },
58 | }
59 | })
60 | ]
61 | })
62 | .then(bundle => {
63 | return bundle
64 | .generate({
65 | format: 'umd',
66 | name: 'component'
67 | })
68 | .then(generated => {
69 | expect(generated.code.includes(`blaah`)).to.equal(true);
70 | assert.ok(generated.code);
71 | });
72 | });
73 | });
74 | });
75 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rollup-plugin-angular",
3 | "version": "0.5.3",
4 | "description": "Angular2 template and styles inliner",
5 | "main": "dist/rollup-plugin-angular.js",
6 | "module": "dist/rollup-plugin-angular.esm.js",
7 | "scripts": {
8 | "build": "rollup -c",
9 | "prepublish": "npm run build",
10 | "test": "npm run build && npm run mocha:test && npm run karma:test",
11 | "karma:test": "./node_modules/karma/bin/karma start karma.conf.js",
12 | "mocha:js": "mocha test/mochajs/index.js --compilers js:buble/register --compilers js:babel-register; exit 0",
13 | "mocha:ts": "mocha test/mochats/index.ts --compilers ts:ts-node/register --timeout 2000; exit 0",
14 | "mocha:test": "npm run build && npm run mocha:js && npm run mocha:ts; exit 0;"
15 | },
16 | "keywords": [
17 | "angular2",
18 | "template",
19 | "styles",
20 | "inliner",
21 | "rollup-plugin"
22 | ],
23 | "files": [
24 | "dist"
25 | ],
26 | "author": "Felix Itzenplitz",
27 | "repository": {
28 | "type": "git",
29 | "url": "https://github.com/cebor/rollup-plugin-angular.git"
30 | },
31 | "license": "MIT",
32 | "dependencies": {
33 | "colors": "^1.1.2",
34 | "magic-string": "^0.22.4",
35 | "replace": "^0.3.0",
36 | "rollup-pluginutils": "^2.0.1"
37 | },
38 | "devDependencies": {
39 | "@angular/common": "^4.3.5",
40 | "@angular/compiler": "^4.3.5",
41 | "@angular/core": "^4.3.5",
42 | "@angular/platform-browser": "^4.3.5",
43 | "@angular/platform-browser-dynamic": "^4.3.5",
44 | "@types/chai": "^4.0.4",
45 | "@types/jasmine": "^2.5.54",
46 | "@types/karma": "^0.13.36",
47 | "@types/mocha": "^2.2.42",
48 | "@types/node": "^8.0.24",
49 | "babel-register": "^6.26.0",
50 | "chai": "^4.1.1",
51 | "clean-css": "^4.1.7",
52 | "html-minifier": "^3.5.3",
53 | "jasmine": "^2.7.0",
54 | "jasmine-core": "^2.7.0",
55 | "karma": "^1.7.0",
56 | "karma-chrome-launcher": "^2.2.0",
57 | "karma-coverage": "^1.1.1",
58 | "karma-firefox-launcher": "^1.0.1",
59 | "karma-jasmine": "^1.1.0",
60 | "karma-rollup-preprocessor": "^4.0.4",
61 | "mocha": "^3.5.0",
62 | "node-sass": "^4.5.3",
63 | "reflect-metadata": "^0.1.10",
64 | "rollup": "^0.48.2",
65 | "rollup-plugin-buble": "^0.15.0",
66 | "rollup-plugin-commonjs": "^8.2.0",
67 | "rollup-plugin-node-resolve": "^3.0.0",
68 | "rollup-plugin-typescript": "^0.8.1",
69 | "rxjs": "^5.4.3",
70 | "ts-node": "^3.3.0",
71 | "typescript": "^2.5.1",
72 | "zone.js": "^0.8.16"
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://travis-ci.org/cebor/rollup-plugin-angular)
2 |
3 | # rollup-plugin-angular
4 | Angular2 template and styles inliner for rollup
5 |
6 | ## Looking for new maintainer
7 | I have no time to maintain this plugin anymore. So im looking for a new Maintainer. Feel free to create an issue, when you want to maintain this plugin.
8 |
9 | ## Installation
10 | ```bash
11 | npm install --save-dev rollup-plugin-angular
12 | ```
13 |
14 | ## Example
15 | ```javascript
16 | // rollup.config.js
17 | import angular from 'rollup-plugin-angular';
18 | import typescript from 'rollup-plugin-typescript';
19 | import alias from 'rollup-plugin-alias';
20 | import nodeResolve from 'rollup-plugin-node-resolve';
21 |
22 | export default {
23 | entry: 'src/main.ts',
24 | format: 'iife',
25 | dest: 'dist/bundle.js',
26 | plugins: [
27 | angular(),
28 | typescript(),
29 | alias({ rxjs: __dirname + '/node_modules/rxjs-es' }), // rxjs fix (npm install rxjs-es)
30 | nodeResolve({ jsnext: true, main: true })
31 | ]
32 | }
33 | ```
34 |
35 | ## Template & Style preprocessing
36 | You may need to do some preprocessing on your templates & styles such as minification and/or transpilation.
37 |
38 | To do this you can pass a preprocessors object as an option, containing a style and/or template preprocessor.
39 |
40 | If you are using rollup on a source that has already been transpiled to JavaScript you will also need to set the sourcetype.
41 |
42 | ### Signature
43 | ```typescript
44 | sourcetype: 'js' //defaults to 'ts'
45 | preprocessors: {
46 | template: (source: string, path: string) => string,
47 | style: (source: string, path: string) => string,
48 | }
49 | ```
50 | `source` - The contents of the style or template's file.
51 |
52 | `path` - The path to the loaded file. Can be useful for checking file extensions for example.
53 |
54 | returns the manipulated source as a string.
55 |
56 | ### Example
57 | The following example shows how you can use sass, clean-css (for css minification), and htmlmin.
58 |
59 | ```javascript
60 | // rollup.config.js
61 | import angular from 'rollup-plugin-angular';
62 | import typescript from 'rollup-plugin-typescript';
63 | import nodeResolve from 'rollup-plugin-node-resolve';
64 | import sass from 'node-sass';
65 | import CleanCSS from 'clean-css';
66 | import { minify as minifyHtml } from 'html-minifier';
67 |
68 | const cssmin = new CleanCSS();
69 | const htmlminOpts = {
70 | caseSensitive: true,
71 | collapseWhitespace: true,
72 | removeComments: true,
73 | };
74 |
75 | export default {
76 | input: 'src/main.ts',
77 | output: {
78 | format: 'umd',
79 | file: 'dist/bundle.js'
80 | },
81 | plugins: [
82 | angular({
83 | // additional replace `templateUrl` and `stylesUrls` in every `.js` file
84 | // default: true
85 | replace: false,
86 | preprocessors: {
87 | template: template => minifyHtml(template, htmlminOpts),
88 | style: scss => {
89 | const css = sass.renderSync({ data: scss }).css;
90 | return cssmin.minify(css).styles;
91 | },
92 | }
93 | })
94 | typescript(),
95 | nodeResolve({ jsnext: true, main: true })
96 | ]
97 | }
98 | ```
99 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration
2 |
3 | const angular = require('./dist/rollup-plugin-angular.js');
4 | const commonjs = require('rollup-plugin-commonjs');
5 | const nodeResolve = require('rollup-plugin-node-resolve');
6 | const typescript = require('rollup-plugin-typescript');
7 |
8 | module.exports = function(config) {
9 | config.set({
10 |
11 | // base path that will be used to resolve all patterns (eg. files, exclude)
12 | basePath: '',
13 |
14 |
15 | // frameworks to use
16 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
17 | frameworks: ['jasmine'],
18 |
19 |
20 | // list of files / patterns to load in the browser
21 | files: [
22 | 'test/karma/*.ts'
23 | ],
24 |
25 |
26 | plugins: [
27 | require('karma-coverage'),
28 | require('karma-chrome-launcher'),
29 | require('karma-firefox-launcher'),
30 | require('karma-rollup-preprocessor'),
31 | require('karma-jasmine')
32 | ],
33 |
34 |
35 | // list of files to exclude
36 | exclude: [],
37 |
38 |
39 | // preprocess matching files before serving them to the browser
40 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
41 | preprocessors: {
42 | 'test/karma/*.ts': ['rollup']
43 | },
44 |
45 |
46 | rollupPreprocessor: {
47 | context: 'this',
48 | // will help to prevent conflicts between different tests entries
49 | moduleName: 'examplemodule',
50 | format: 'umd',
51 | sourceMap: 'inline',
52 | // rollup settings. See Rollup documentation
53 | plugins: [
54 | angular(),
55 | commonjs(),
56 | nodeResolve({
57 | // use "es2015" field for ES2015 modules with ES2015 code,
58 | // if possible
59 | es2015: true, // Default: false
60 |
61 | // use "module" field for ES2015 modules with ES5 code,
62 | // if possible
63 | module: true, // Default: true
64 |
65 | // use "jsnext:main" if possible
66 | // – see https://github.com/rollup/rollup/wiki/jsnext:main
67 | jsnext: true, // Default: false
68 |
69 | // use "main" field or index.js, even if it's not an ES6 module
70 | // (needs to be converted from CommonJS to ES6
71 | // – see https://github.com/rollup/rollup-plugin-commonjs
72 | main: true, // Default: true
73 |
74 | extensions: [ '.js', '.json' ]
75 | }),
76 | typescript({
77 | typescript: require('./node_modules/typescript')
78 | }),
79 | ],
80 | },
81 |
82 |
83 | // test results reporter to use
84 | // possible values: 'dots', 'progress'
85 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter
86 | reporters: ['progress'],
87 |
88 |
89 | // web server port
90 | port: 9876,
91 |
92 |
93 | // enable / disable colors in the output (reporters and logs)
94 | colors: true,
95 |
96 |
97 | // level of logging
98 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
99 | logLevel: config.LOG_INFO,
100 |
101 |
102 | // enable / disable watching file and executing tests whenever any file changes
103 | autoWatch: true,
104 |
105 |
106 | mime: {
107 | 'text/x-typescript': ['ts','tsx']
108 | },
109 |
110 |
111 | // start these browsers
112 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
113 | browsers: ['Firefox'],
114 |
115 | // Continuous Integration mode
116 | // if true, Karma captures browsers, runs the tests and exits
117 | singleRun: true,
118 |
119 | // Concurrency level
120 | // how many browser should be started simultaneous
121 | concurrency: Infinity
122 | })
123 | }
124 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import path from 'path';
3 | import * as colors from 'colors';
4 | import replace from 'replace';
5 |
6 | import MagicString from 'magic-string';
7 | import { createFilter } from 'rollup-pluginutils';
8 |
9 | const moduleIdRegex = /moduleId\s*:(.*)/g;
10 | const componentRegex = /@Component\(\s?{([\s\S]*)}\s?\)$|type:\s?Component,\s?args:\s?\[\s?{([\s\S]*)},\s?\]/gm;
11 | const commentRegex = /\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm; // http://www.regextester.com/?fam=96247
12 | const templateUrlRegex = /templateUrl\s*:(.*)/g;
13 | const styleUrlsRegex = /styleUrls\s*:(\s*\[[\s\S]*?\])/g; // http://www.regextester.com/?fam=98594
14 | const stringRegex = /(['"`])((?:[^\\]\\\1|.)*?)\1/g;
15 |
16 | function insertText(str, dir, preprocessor = res => res, processFilename = false, sourceType = 'ts') {
17 | let quoteChar = sourceType === 'ts' ? '`' : '"';
18 | return str.replace(stringRegex, function (match, quote, url) {
19 | const includePath = path.join(dir, url);
20 | if (processFilename) {
21 | return quoteChar + preprocessor(includePath) + quoteChar;
22 | }
23 | const text = fs.readFileSync(includePath).toString();
24 | return quoteChar + preprocessor(text, includePath) + quoteChar;
25 | });
26 | }
27 |
28 | export default function angular(options = {}) {
29 | options.preprocessors = options.preprocessors || {}; // set default preprocessors to `{}`
30 | options.replace = (typeof options.replace === 'boolean') ? options.replace : true; // set default replace to `true`
31 |
32 | // ignore @angular/** modules
33 | options.exclude = options.exclude || [];
34 | if (typeof options.exclude === 'string' || options.exclude instanceof String) {
35 | options.exclude = [options.exclude];
36 | }
37 | if (options.exclude.indexOf('node_modules/@angular/**') === -1) {
38 | options.exclude.push('node_modules/@angular/**');
39 | }
40 |
41 | const filter = createFilter(options.include, options.exclude);
42 |
43 | return {
44 | name: 'angular',
45 | transform(source, map) {
46 | if (!filter(map)) return;
47 | // replace comments in source
48 | source = source.replace(commentRegex, '');
49 | // use MagicString
50 | const magicString = new MagicString(source);
51 | // get dir from `map`
52 | const dir = path.parse(map).dir;
53 | // get file extension from `map`
54 | const fileExt = map.split('.').pop();
55 |
56 | let hasReplacements = false;
57 | let match;
58 | let start, end, replacement;
59 |
60 | while ((match = componentRegex.exec(source)) !== null) {
61 | start = match.index;
62 | end = start + match[0].length;
63 |
64 | replacement = match[0]
65 | .replace(templateUrlRegex, function (match, url) {
66 | hasReplacements = true;
67 | const toReplace = 'template:' + insertText(url, dir, options.preprocessors.template, options.processFilename, options.sourcetype);
68 | if (fileExt === 'js' && options.replace === true) {
69 | /* replace templateUrl in files generated by ngc */
70 | replace({
71 | regex: match,
72 | replacement: toReplace,
73 | paths: [map],
74 | recursive: true,
75 | silent: true,
76 | });
77 | console.info(`templateUrl in file ${map} has been changed from ${colors.green(match)} to ${colors.green(toReplace)}`);
78 | }
79 | return toReplace;
80 | })
81 | .replace(styleUrlsRegex, function (match, urls) {
82 | hasReplacements = true;
83 | const toReplace = 'styles:' + insertText(urls, dir, options.preprocessors.style, options.processFilename, options.sourcetype);
84 | /* replace styles in files generated by ngc */
85 | if (fileExt === 'js' && options.replace === true) {
86 | replace({
87 | regex: styleUrlsRegex,
88 | replacement: toReplace,
89 | paths: [map],
90 | recursive: true,
91 | silent: true,
92 | });
93 | console.info(`styleUrls in file ${map} has been changed from ${colors.green(match)} to ${colors.green(toReplace)}`);
94 | }
95 | return toReplace;
96 | })
97 | .replace(moduleIdRegex, function (match, moduleId) {
98 | hasReplacements = true;
99 | return '';
100 | });
101 | if (hasReplacements) {
102 | magicString.overwrite(start, end, replacement);
103 | }
104 | }
105 |
106 | if (!hasReplacements) {
107 | return null;
108 | }
109 |
110 | let result = { code: magicString.toString() };
111 |
112 | if (options.sourceMap !== false) {
113 | result.map = magicString.generateMap({ hires: true });
114 | }
115 | return result;
116 | }
117 | };
118 | }
119 |
--------------------------------------------------------------------------------