├── test
├── fixtures
│ ├── bulk
│ │ ├── useref.56.css
│ │ ├── useref.01.css
│ │ ├── useref.02.css
│ │ ├── useref.03.css
│ │ ├── useref.04.css
│ │ ├── useref.05.css
│ │ ├── useref.06.css
│ │ ├── useref.07.css
│ │ ├── useref.08.css
│ │ ├── useref.09.css
│ │ ├── useref.10.css
│ │ ├── useref.11.css
│ │ ├── useref.12.css
│ │ ├── useref.13.css
│ │ ├── useref.14.css
│ │ ├── useref.15.css
│ │ ├── useref.16.css
│ │ ├── useref.17.css
│ │ ├── useref.18.css
│ │ ├── useref.19.css
│ │ ├── useref.20.css
│ │ ├── useref.21.css
│ │ ├── useref.22.css
│ │ ├── useref.23.css
│ │ ├── useref.24.css
│ │ ├── useref.25.css
│ │ ├── useref.26.css
│ │ ├── useref.27.css
│ │ ├── useref.28.css
│ │ ├── useref.29.css
│ │ ├── useref.30.css
│ │ ├── useref.31.css
│ │ ├── useref.32.css
│ │ ├── useref.33.css
│ │ ├── useref.34.css
│ │ ├── useref.35.css
│ │ ├── useref.36.css
│ │ ├── useref.37.css
│ │ ├── useref.38.css
│ │ ├── useref.39.css
│ │ ├── useref.40.css
│ │ ├── useref.41.css
│ │ ├── useref.42.css
│ │ ├── useref.43.css
│ │ ├── useref.44.css
│ │ ├── useref.45.css
│ │ ├── useref.46.css
│ │ ├── useref.47.css
│ │ ├── useref.48.css
│ │ ├── useref.49.css
│ │ ├── useref.50.css
│ │ ├── useref.51.css
│ │ ├── useref.52.css
│ │ ├── useref.53.css
│ │ ├── useref.54.css
│ │ ├── useref.55.css
│ │ ├── useref.01.html
│ │ ├── useref.02.html
│ │ ├── useref.03.html
│ │ ├── useref.04.html
│ │ ├── useref.05.html
│ │ ├── useref.06.html
│ │ ├── useref.07.html
│ │ ├── useref.08.html
│ │ ├── useref.09.html
│ │ ├── useref.10.html
│ │ ├── useref.11.html
│ │ ├── useref.12.html
│ │ ├── useref.13.html
│ │ ├── useref.14.html
│ │ ├── useref.15.html
│ │ ├── useref.16.html
│ │ ├── useref.17.html
│ │ ├── useref.18.html
│ │ ├── useref.19.html
│ │ ├── useref.20.html
│ │ ├── useref.21.html
│ │ ├── useref.22.html
│ │ ├── useref.23.html
│ │ ├── useref.24.html
│ │ ├── useref.25.html
│ │ ├── useref.26.html
│ │ ├── useref.27.html
│ │ ├── useref.28.html
│ │ ├── useref.29.html
│ │ ├── useref.30.html
│ │ ├── useref.31.html
│ │ ├── useref.32.html
│ │ ├── useref.33.html
│ │ ├── useref.34.html
│ │ ├── useref.35.html
│ │ ├── useref.36.html
│ │ ├── useref.37.html
│ │ ├── useref.38.html
│ │ ├── useref.39.html
│ │ ├── useref.40.html
│ │ ├── useref.41.html
│ │ ├── useref.42.html
│ │ ├── useref.43.html
│ │ ├── useref.44.html
│ │ ├── useref.45.html
│ │ ├── useref.46.html
│ │ ├── useref.47.html
│ │ ├── useref.48.html
│ │ ├── useref.49.html
│ │ ├── useref.50.html
│ │ ├── useref.51.html
│ │ ├── useref.52.html
│ │ ├── useref.53.html
│ │ ├── useref.54.html
│ │ ├── useref.55.html
│ │ └── useref.56.html
│ ├── css
│ │ ├── a.css
│ │ ├── z.css
│ │ ├── one.css
│ │ ├── four.css
│ │ ├── two.css
│ │ └── three.css
│ ├── scripts
│ │ ├── that.js
│ │ ├── this.js
│ │ ├── anotherone.js
│ │ └── yetonemore.js
│ ├── relative
│ │ ├── styles
│ │ │ └── main.css
│ │ ├── index.html
│ │ └── child
│ │ │ └── index.html
│ ├── 09.html
│ ├── custom-blocks.html
│ ├── order.html
│ ├── nonexistent.html
│ ├── templates1
│ │ └── component.html
│ ├── templates2
│ │ └── component.html
│ ├── 01.html
│ ├── 05.html
│ ├── absolute-search-path.html
│ ├── 02.html
│ ├── 10.html
│ ├── 06.html
│ ├── remote-path.html
│ ├── bad-path.html
│ ├── 03.html
│ ├── 12.html
│ ├── 11.html
│ ├── 07.html
│ ├── alternate-search-paths.html
│ ├── 08.html
│ └── 04.html
├── .tmp
│ ├── css
│ │ ├── one.css
│ │ └── two.css
│ └── scripts
│ │ ├── that.js
│ │ ├── module1.js
│ │ ├── module2.js
│ │ ├── this.js
│ │ ├── anotherone.js
│ │ └── yetonemore.js
├── expected
│ ├── css
│ │ └── ordered.css
│ ├── custom-blocks.html
│ ├── 01.html
│ ├── 02.html
│ ├── 03.html
│ ├── noconcat-css.html
│ ├── noconcat-js.html
│ └── 04.html
├── mock-relative.js
├── mock-all.js
└── test.js
├── .gitignore
├── .npmignore
├── lib
├── addHtmlToStream.js
├── unprocessedCounter.js
├── end.js
├── addFilesFromExtStreams.js
├── getPattern.js
├── getGlobs.js
└── reorderTheStream.js
├── .editorconfig
├── gulpfile.js
├── .github
└── workflows
│ └── main.yml
├── LICENSE
├── package.json
├── .eslintrc.json
├── index.js
├── README.md
└── CONTRIBUTING.md
/test/fixtures/bulk/useref.56.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/css/a.css:
--------------------------------------------------------------------------------
1 | .a {
2 | /* */
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/css/z.css:
--------------------------------------------------------------------------------
1 | .z {
2 | /* */
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | coverage
3 | .nyc_output
4 |
--------------------------------------------------------------------------------
/test/.tmp/css/one.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
--------------------------------------------------------------------------------
/test/.tmp/scripts/that.js:
--------------------------------------------------------------------------------
1 | function ninja(){}
2 | ninja();
--------------------------------------------------------------------------------
/test/fixtures/css/one.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
--------------------------------------------------------------------------------
/test/.tmp/scripts/module1.js:
--------------------------------------------------------------------------------
1 | var x = 'abc';
2 | console.log(x);
--------------------------------------------------------------------------------
/test/.tmp/scripts/module2.js:
--------------------------------------------------------------------------------
1 | function ninja(){}
2 | ninja();
--------------------------------------------------------------------------------
/test/.tmp/scripts/this.js:
--------------------------------------------------------------------------------
1 | var x = 'abc';
2 | console.log(x);
--------------------------------------------------------------------------------
/test/fixtures/scripts/that.js:
--------------------------------------------------------------------------------
1 | function ninja(){}
2 | ninja();
--------------------------------------------------------------------------------
/test/fixtures/scripts/this.js:
--------------------------------------------------------------------------------
1 | var x = 'abc';
2 | console.log(x);
--------------------------------------------------------------------------------
/test/.tmp/scripts/anotherone.js:
--------------------------------------------------------------------------------
1 | var samurai = function(){};
2 | samurai();
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.01.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.02.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.03.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.04.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.05.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.06.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.07.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.08.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.09.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.10.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.11.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.12.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.13.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.14.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.15.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.16.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.17.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.18.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.19.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.20.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.21.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.22.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.23.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.24.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.25.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.26.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.27.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.28.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.29.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.30.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.31.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.32.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.33.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.34.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.35.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.36.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.37.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.38.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.39.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.40.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.41.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.42.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.43.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.44.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.45.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.46.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.47.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.48.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.49.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.50.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.51.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.52.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.53.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.54.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.55.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/relative/styles/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #333;
3 | }
--------------------------------------------------------------------------------
/test/fixtures/scripts/anotherone.js:
--------------------------------------------------------------------------------
1 | var samurai = function(){};
2 | samurai();
--------------------------------------------------------------------------------
/test/.tmp/scripts/yetonemore.js:
--------------------------------------------------------------------------------
1 | var o = {};
2 | o.whatever = function(){};
3 | o.whatever();
--------------------------------------------------------------------------------
/test/expected/css/ordered.css:
--------------------------------------------------------------------------------
1 | .z {
2 | /* */
3 | }
4 |
5 | .a {
6 | /* */
7 | }
8 |
--------------------------------------------------------------------------------
/test/fixtures/scripts/yetonemore.js:
--------------------------------------------------------------------------------
1 | var o = {};
2 | o.whatever = function(){};
3 | o.whatever();
--------------------------------------------------------------------------------
/test/expected/custom-blocks.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | customResult
5 |
6 |
7 |
--------------------------------------------------------------------------------
/test/fixtures/css/four.css:
--------------------------------------------------------------------------------
1 | #page {
2 | margin: 0 1em;
3 | }
4 | #header {
5 | margin: 1em 0 2em;
6 | }
--------------------------------------------------------------------------------
/test/expected/01.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/test/expected/02.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/test/fixtures/09.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .editorconfig
2 | .travis.yml
3 | .jscsrc
4 | .jshintrc
5 | .gitattributes
6 | CONTRIBUTING.md
7 | gulpfile.js
8 | test
9 |
--------------------------------------------------------------------------------
/test/.tmp/css/two.css:
--------------------------------------------------------------------------------
1 | a,
2 | a:visited {
3 | color: #003F87;
4 | }
5 | a:hover,
6 | a:focus,
7 | a:active {
8 | color: #CCC;
9 | }
--------------------------------------------------------------------------------
/test/expected/03.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/test/fixtures/css/two.css:
--------------------------------------------------------------------------------
1 | a,
2 | a:visited {
3 | color: #003F87;
4 | }
5 | a:hover,
6 | a:focus,
7 | a:active {
8 | color: #CCC;
9 | }
--------------------------------------------------------------------------------
/test/expected/noconcat-css.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/test/fixtures/custom-blocks.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | someContent
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/order.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/test/fixtures/nonexistent.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/test/fixtures/relative/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/test/fixtures/templates1/component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/test/fixtures/templates2/component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/test/fixtures/relative/child/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/test/expected/noconcat-js.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/test/fixtures/css/three.css:
--------------------------------------------------------------------------------
1 | .clearfix:after {
2 | content: "";
3 | display:table;
4 | clear:both;
5 | }
6 | .ir {
7 | text-indent: 100%;
8 | white-space:nowrap;
9 | overflow:hidden;
10 | }
--------------------------------------------------------------------------------
/test/fixtures/01.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/test/fixtures/05.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/test/fixtures/absolute-search-path.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/02.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/10.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/06.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/remote-path.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bad-path.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.01.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.02.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.03.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.04.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.05.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.06.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.07.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.08.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.09.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.10.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.11.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.12.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.13.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.14.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.15.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.16.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.17.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.18.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.19.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.20.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.21.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.22.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.23.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.24.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.25.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.26.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.27.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.28.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.29.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.30.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.31.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.32.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.33.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.34.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.35.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.36.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.37.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.38.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.39.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.40.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.41.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.42.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.43.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.44.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.45.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.46.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.47.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.48.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.49.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.50.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.51.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.52.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.53.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.54.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.55.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/03.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/lib/addHtmlToStream.js:
--------------------------------------------------------------------------------
1 | const PluginError = require('plugin-error');
2 |
3 | module.exports = function (file, data) {
4 | const self = this;
5 |
6 | try {
7 | file.contents = Buffer.from(data);
8 | self.push(file);
9 | } catch (err) {
10 | self.emit('error', new PluginError('gulp-useref', err));
11 | }
12 | };
13 |
--------------------------------------------------------------------------------
/test/expected/04.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/test/fixtures/12.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/test/fixtures/11.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/lib/unprocessedCounter.js:
--------------------------------------------------------------------------------
1 | module.exports = () => {
2 | let unprocessed = 0;
3 |
4 | return {
5 | get() {
6 | return unprocessed;
7 | },
8 |
9 | increment() {
10 | return unprocessed++;
11 | },
12 |
13 | decrement() {
14 | return --unprocessed;
15 | }
16 | };
17 | };
18 |
--------------------------------------------------------------------------------
/lib/end.js:
--------------------------------------------------------------------------------
1 | module.exports = () => {
2 | let _end;
3 |
4 | function get() {
5 | return _end;
6 | }
7 |
8 | function set(cb) {
9 | _end = cb;
10 |
11 | return _end;
12 | }
13 |
14 | function fn() {
15 | return _end();
16 | }
17 |
18 | return {
19 | get,
20 | set,
21 | fn
22 | };
23 | };
24 |
--------------------------------------------------------------------------------
/test/fixtures/07.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/test/fixtures/alternate-search-paths.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/lib/addFilesFromExtStreams.js:
--------------------------------------------------------------------------------
1 | const reorderTheStream = require('./reorderTheStream');
2 |
3 | module.exports = function (additionalFiles, globs, src) {
4 | const self = this;
5 | let source;
6 |
7 | additionalFiles.forEach(addFile => {
8 | src.push(addFile);
9 | });
10 |
11 | // if we added additional files, reorder the stream
12 | if (additionalFiles.length > 0) {
13 | source = reorderTheStream.call(self, globs, src);
14 | }
15 |
16 | return source || src;
17 | };
18 |
--------------------------------------------------------------------------------
/lib/getPattern.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | module.exports = (files, paths) => {
4 | let searchPaths;
5 | const destPath = paths.destPath;
6 | const searchPath = paths.searchPath;
7 | const cwd = paths.cwd;
8 | const basePath = paths.basePath;
9 | const srcPath = paths.srcPath;
10 |
11 | if (files[destPath].searchPaths || searchPath) {
12 | searchPaths = path.resolve(cwd, files[destPath].searchPaths || searchPath);
13 | }
14 | return (searchPaths || basePath) + path.sep + srcPath;
15 | };
16 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 |
10 | # Change these settings to your own preference
11 | indent_style = space
12 | indent_size = 4
13 |
14 | # We recommend you to keep these unchanged
15 | end_of_line = lf
16 | charset = utf-8
17 | trim_trailing_whitespace = true
18 | insert_final_newline = true
19 |
20 | [*.md]
21 | trim_trailing_whitespace = false
22 |
23 | [{package.json,*.yml}]
24 | indent_style = space
25 | indent_size = 2
26 |
--------------------------------------------------------------------------------
/test/fixtures/08.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | const gulp = require('gulp');
3 | const mocha = require('gulp-mocha');
4 | const eslint = require('gulp-eslint');
5 |
6 | const paths = {
7 | scripts: ['./*.js', './lib/*.js', '!./gulpfile.js']
8 | };
9 |
10 | gulp.task('lint', () => gulp.src(paths.scripts)
11 | .pipe(eslint({fix: true}))
12 | .pipe(eslint.format())
13 | .pipe(eslint.failAfterError()));
14 |
15 | gulp.task('test', () => gulp.src('./test/*.js')
16 | .pipe(mocha({ reporter: 'spec' })));
17 |
18 | gulp.task('watch', () => {
19 | gulp.watch(paths.scripts, gulp.parallel('lint', 'test'));
20 | });
21 |
22 | gulp.task('default', gulp.parallel('lint', 'test', 'watch'));
23 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 | branches:
9 | - master
10 |
11 | jobs:
12 | test:
13 |
14 | runs-on: ubuntu-latest
15 |
16 | strategy:
17 | fail-fast: false
18 | matrix:
19 | node-version: [12.x, 14.x, 16.x]
20 |
21 | steps:
22 | - uses: actions/checkout@v2
23 | - name: Node.js ${{ matrix.node-version }}
24 | uses: actions/setup-node@v2
25 | with:
26 | node-version: ${{ matrix.node-version }}
27 | - run: npm install
28 | - run: gulp lint
29 | - run: npm test
30 | - run: npm run coveralls
31 |
32 | - name: Coveralls
33 | uses: coverallsapp/github-action@master
34 | with:
35 | github-token: ${{ secrets.GITHUB_TOKEN }}
36 |
--------------------------------------------------------------------------------
/test/fixtures/04.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/lib/getGlobs.js:
--------------------------------------------------------------------------------
1 | const getPattern = require('./getPattern');
2 |
3 | module.exports = (paths, files) => {
4 | let pattern;
5 | let matches;
6 | const glob = require('glob');
7 | let searchPath = paths.searchPath;
8 | const name = paths.name;
9 | const cwd = paths.cwd;
10 | const basePath = paths.basePath;
11 | const filepath = paths.filepath;
12 | const transformPath = paths.transformPath;
13 |
14 | if (searchPath && Array.isArray(searchPath)) {
15 | searchPath = searchPath.length === 1 ? searchPath[0] : `{${searchPath.join(',')}}`;
16 | }
17 |
18 | pattern = getPattern(files, {
19 | destPath: name,
20 | searchPath,
21 | cwd,
22 | basePath,
23 | srcPath: filepath
24 | });
25 |
26 | matches = glob.sync(pattern, { nosort: true });
27 |
28 | if (!matches.length) {
29 | matches.push(pattern);
30 | }
31 |
32 | if (transformPath) {
33 | matches[0] = transformPath(matches[0]);
34 | }
35 |
36 | return matches[0];
37 | };
38 |
--------------------------------------------------------------------------------
/lib/reorderTheStream.js:
--------------------------------------------------------------------------------
1 | const through = require('through2');
2 |
3 | module.exports = function (globs, src) {
4 | const self = this;
5 | const sortIndex = {};
6 | let i = 0;
7 | const sortedFiles = [];
8 | const unsortedFiles = [];
9 |
10 | // Create a sort index so we don't iterate over the globs for every file
11 | globs.forEach(filename => {
12 | sortIndex[filename] = i++;
13 | });
14 |
15 | return src.pipe(through.obj((srcFile, encoding, callback) => {
16 | const index = sortIndex[srcFile.path];
17 |
18 | if (index === undefined) {
19 | unsortedFiles.push(srcFile);
20 | } else {
21 | sortedFiles[index] = srcFile;
22 | }
23 | callback();
24 | }, callback => {
25 | sortedFiles.forEach(function (sorted) {
26 | if (sorted !== undefined) {
27 | this.push(sorted);
28 | }
29 | }, self);
30 |
31 | unsortedFiles.forEach(function (unsorted) {
32 | this.push(unsorted);
33 | }, self);
34 | callback();
35 | }));
36 | };
37 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Jonathan Kemp
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.
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gulp-useref",
3 | "version": "5.0.0",
4 | "description": "Parse build blocks in HTML files to replace references to non-optimized scripts or stylesheets.",
5 | "main": "index.js",
6 | "directories": {
7 | "test": "test"
8 | },
9 | "dependencies": {
10 | "event-stream": "^4.0.1",
11 | "extend": "^3.0.2",
12 | "glob": "^7.2.0",
13 | "gulp-concat": "^2.6.1",
14 | "gulp-if": "^3.0.0",
15 | "plugin-error": "^1.0.1",
16 | "through2": "^4.0.2",
17 | "useref": "^1.4.4",
18 | "vinyl-fs": "^3.0.3"
19 | },
20 | "devDependencies": {
21 | "async-once": "^1.0.1",
22 | "babel-eslint": "^10.1.0",
23 | "coveralls": "^3.1.1",
24 | "gulp": "^4.0.2",
25 | "gulp-eslint": "^6.0.0",
26 | "gulp-mocha": "^8.0.0",
27 | "gulp-rename": "^2.0.0",
28 | "mocha": "^9.2.2",
29 | "mock-gulp-dest": "^0.1.1",
30 | "nyc": "^15.1.0",
31 | "should": "*",
32 | "vinyl": "^2.2.1"
33 | },
34 | "engines": {
35 | "node": ">=0.10.0"
36 | },
37 | "scripts": {
38 | "test": "mocha",
39 | "lint": "gulp lint",
40 | "coverage": "nyc npm test && nyc report",
41 | "coveralls": "nyc npm test && nyc report --reporter=lcov"
42 | },
43 | "files": [
44 | "index.js",
45 | "lib"
46 | ],
47 | "repository": "jonkemp/gulp-useref",
48 | "keywords": [
49 | "gulpplugin",
50 | "html",
51 | "scripts",
52 | "css",
53 | "optimize",
54 | "concat"
55 | ],
56 | "author": "Jonathan Kemp (http://jonkemp.com/)",
57 | "license": "MIT"
58 | }
59 |
--------------------------------------------------------------------------------
/test/mock-relative.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | /* global describe, it */
3 |
4 | const should = require('should');
5 | const path = require('path');
6 | const once = require('async-once');
7 |
8 | describe('relative files', function () {
9 | this.timeout(5000);
10 |
11 | it('should handle relative files', done => {
12 | let seriesFn;
13 | const gulp = require('gulp');
14 | const mockGulpDest = require('mock-gulp-dest')(gulp);
15 | const useref = require('../index');
16 |
17 | function relative() {
18 | return gulp.src('test/fixtures/relative/**/*.html')
19 | .pipe(useref())
20 | .pipe(gulp.dest('fixtures/relative/styles', { cwd: 'test' }));
21 | }
22 |
23 | seriesFn = gulp.series(relative, once(() => {
24 | mockGulpDest.cwd().should.equal(__dirname);
25 | mockGulpDest.basePath().should.equal(path.join(__dirname, 'fixtures/relative/styles'));
26 | mockGulpDest.assertDestContains([
27 | 'bundle.css'
28 | ]);
29 |
30 | done();
31 | }));
32 |
33 | seriesFn();
34 | });
35 |
36 | it('should handle relative files when base is set', done => {
37 | let seriesFn;
38 | const gulp = require('gulp');
39 | const mockGulpDest = require('mock-gulp-dest')(gulp);
40 | const useref = require('../index');
41 |
42 | function relativeBase() {
43 | return gulp.src(['test/fixtures/templates1/**/*.html', 'test/fixtures/templates2/**/*.html'])
44 | .pipe(useref({
45 | searchPath: 'test/fixtures',
46 | base: 'test/fixtures'
47 | }))
48 | .pipe(gulp.dest('test/dist'));
49 | }
50 |
51 | seriesFn = gulp.series(relativeBase, once(() => {
52 | mockGulpDest.basePath().should.equal(path.join(__dirname, 'dist'));
53 | mockGulpDest.assertDestContains([
54 | 'css/bundle.css',
55 | 'css/combined.css'
56 | ]);
57 |
58 | done();
59 | }));
60 |
61 | seriesFn();
62 | });
63 | });
64 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "mocha": true,
4 | "node": true
5 | },
6 | "globals": {},
7 | "extends": "eslint:recommended",
8 |
9 | // Stop ESLint from looking for a configuration file in parent folders
10 | "root": true,
11 |
12 | "parser": "babel-eslint",
13 | "parserOptions": {
14 | "ecmaVersion": 8,
15 | "sourceType": "script",
16 | "ecmaFeatures": {
17 | "experimentalObjectRestSpread": true
18 | }
19 | },
20 | "rules": {
21 | "block-scoped-var": 2,
22 | "complexity": [
23 | 0,
24 | 5
25 | ],
26 | "consistent-return": 1,
27 | "curly": [
28 | 2,
29 | "all"
30 | ],
31 | "dot-notation": 2,
32 | "eqeqeq": 2,
33 | "no-caller": 2,
34 | "no-else-return": 2,
35 | "no-eq-null": 2,
36 | "no-extend-native": 2,
37 | "no-implicit-coercion": 2,
38 | "no-loop-func": 2,
39 | "no-multi-spaces": 2,
40 | "no-multi-str": 2,
41 | "no-new-func": 2,
42 | "no-new-wrappers": 2,
43 | "no-new": 2,
44 | "no-param-reassign": 2,
45 | "no-unused-expressions": 2,
46 | "no-useless-call": 2,
47 | "no-useless-concat": 2,
48 | "no-with": 2,
49 | "vars-on-top": 2,
50 | "wrap-iife": [2, "any"],
51 | "yoda": [
52 | 2,
53 | "never"
54 | ],
55 |
56 | "no-shadow": 2,
57 | "no-use-before-define": 2,
58 |
59 | "callback-return": 2,
60 | "handle-callback-err": 2,
61 | "no-path-concat": 2,
62 |
63 | "array-bracket-spacing": [
64 | 1,
65 | "always", {
66 | "objectsInArrays": false
67 | }
68 | ],
69 | "block-spacing": 1,
70 | "brace-style": 1,
71 | "camelcase": [
72 | 1, {
73 | "properties": "never"
74 | }
75 | ],
76 | "comma-spacing": [
77 | 1, {
78 | "before": false,
79 | "after": true
80 | }
81 | ],
82 | "comma-style": [
83 | 1,
84 | "last"
85 | ],
86 | "computed-property-spacing": [
87 | 1,
88 | "never"
89 | ],
90 | "consistent-this": [
91 | 1,
92 | "self"
93 | ],
94 | "eol-last": 1,
95 | "indent": [
96 | 2,
97 | 4, {
98 | "SwitchCase": 1
99 | }
100 | ],
101 | "key-spacing": [
102 | 1, {
103 | "beforeColon": false,
104 | "afterColon": true
105 | }
106 | ],
107 | "keyword-spacing": 1,
108 | "linebreak-style": [
109 | 1,
110 | "unix"
111 | ],
112 | "lines-around-comment": [
113 | 1, {
114 | "allowBlockStart": true,
115 | "beforeBlockComment": true,
116 | "beforeLineComment": true
117 | }
118 | ],
119 | "max-depth": [
120 | 1,
121 | 4
122 | ],
123 | "max-params": [
124 | 1,
125 | 3
126 | ],
127 | "max-statements": [
128 | 0,
129 | 10
130 | ],
131 | "new-cap": 2,
132 | "new-parens": 2,
133 | "padding-line-between-statements": [
134 | "error",
135 | { "blankLine": "always", "prev": ["const", "let", "var"], "next": "*"},
136 | { "blankLine": "any", "prev": ["const", "let", "var"], "next": ["const", "let", "var"]}
137 | ],
138 | "no-array-constructor": 2,
139 | "no-bitwise": 1,
140 | "no-lonely-if": 1,
141 | "no-multiple-empty-lines": 1,
142 | "no-new-object": 2,
143 | "no-spaced-func": 1,
144 | "no-trailing-spaces": 1,
145 | "no-unneeded-ternary": 1,
146 | "object-curly-spacing": [
147 | 1,
148 | "always"
149 | ],
150 | "operator-assignment": [
151 | 1,
152 | "always"
153 | ],
154 | "operator-linebreak": [
155 | 1,
156 | "after"
157 | ],
158 | "quote-props": [
159 | 1,
160 | "as-needed"
161 | ],
162 | "quotes": [
163 | 1,
164 | "single"
165 | ],
166 | "semi": [
167 | 2,
168 | "always"
169 | ],
170 | "semi-spacing": [
171 | 1, {
172 | "before": false,
173 | "after": true
174 | }
175 | ],
176 | "space-before-blocks": [
177 | 1,
178 | "always"
179 | ],
180 | "space-before-function-paren": [1, { "anonymous": "always", "named": "never" }],
181 | "space-in-parens": [1, "never"],
182 | "space-infix-ops": 1,
183 | "space-unary-ops": 0,
184 | "spaced-comment": [1, "always", { "line": { "exceptions": ["-"] } }]
185 | }
186 | }
187 |
--------------------------------------------------------------------------------
/test/fixtures/bulk/useref.56.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const PluginError = require('plugin-error');
3 | const es = require('event-stream');
4 | const through = require('through2');
5 | const useref = require('useref');
6 | const getGlobs = require('./lib/getGlobs');
7 | const addFilesFromExtStreams = require('./lib/addFilesFromExtStreams');
8 | const addHtmlToStream = require('./lib/addHtmlToStream');
9 | const unprocessedCounter = require('./lib/unprocessedCounter')();
10 | const end = require('./lib/end')();
11 | const additionalFiles = [];
12 | let transforms;
13 | let pluginOptions;
14 |
15 | function handleAdditionalStreams(additionalStreams) {
16 | let _additionalStreams = additionalStreams;
17 |
18 | if (!Array.isArray(additionalStreams)) {
19 | _additionalStreams = [ additionalStreams ];
20 | }
21 |
22 | // filters stream to select needed files
23 | return _additionalStreams.map(stream => stream.pipe(es.through(file => {
24 | additionalFiles.push(file);
25 | })));
26 | }
27 |
28 | function addAssetsToStream(paths, files) {
29 | const self = this;
30 | const gulpif = require('gulp-if');
31 | const concat = require('gulp-concat');
32 | const vfs = require('vinyl-fs');
33 | const extend = require('extend');
34 | let src;
35 | let globs;
36 | const name = paths.name;
37 | const basePath = paths.basePath;
38 | const filepaths = files[name].assets;
39 | const type = paths.type;
40 | const options = extend({}, pluginOptions);
41 | const gulpConcatOptions = {};
42 |
43 | if (!filepaths.length) {
44 | return;
45 | }
46 |
47 | unprocessedCounter.increment();
48 |
49 | // Get relative file paths and join with search paths to send to vinyl-fs
50 | globs = filepaths
51 | .filter(url => !/^(?:\w+:)?\/\//.test(url)) // test if url is relative
52 | .map(filepath => {
53 | paths.filepath = filepath;
54 |
55 | return getGlobs(paths, files);
56 | });
57 |
58 | src = vfs.src(globs, {
59 | base: basePath,
60 | nosort: true
61 | })
62 | .on('error', err => {
63 | self.emit('error', new Error(err));
64 | });
65 |
66 | // add files from external streams
67 | src = addFilesFromExtStreams.call(self, additionalFiles, globs, src);
68 |
69 | // If any external transforms were included, pipe all files to them first
70 | transforms.forEach(fn => {
71 | src = src.pipe(fn(name));
72 | });
73 |
74 | // option for newLine in gulp-concat
75 | if (Object.prototype.hasOwnProperty.call(options, 'newLine')) {
76 | if (options.newLine === ';' && type === 'css') {
77 | options.newLine = null;
78 | }
79 | gulpConcatOptions.newLine = options.newLine;
80 | }
81 |
82 | // Add assets to the stream
83 | // If noconcat option is false, concat the files first.
84 | src
85 | .pipe(gulpif(!options.noconcat, concat(name, gulpConcatOptions)))
86 | .pipe(through.obj((newFile, encoding, callback) => {
87 | // specify an output path relative to the cwd
88 | if (options.base) {
89 | newFile.path = path.join(options.base, name);
90 | newFile.base = options.base;
91 | }
92 |
93 | // add file to the asset stream
94 | self.push(newFile);
95 | callback();
96 | }))
97 | .on('finish', () => {
98 | const unprocessed = unprocessedCounter.decrement();
99 |
100 | if (unprocessed === 0 && end.get()) {
101 | // end the asset stream
102 | end.fn();
103 | }
104 | });
105 | }
106 |
107 | function processAssets({ cwd }, basePath, data) {
108 | const self = this;
109 | const types = pluginOptions.types || [ 'css', 'js' ];
110 |
111 | types.forEach(type => {
112 | const files = data[type];
113 | let name;
114 |
115 | if (!files) {
116 | return;
117 | }
118 |
119 | for (name in files) {
120 | addAssetsToStream.call(self, {
121 | name,
122 | basePath,
123 | searchPath: pluginOptions.searchPath,
124 | cwd,
125 | transformPath: pluginOptions.transformPath,
126 | type
127 | }, files);
128 | }
129 | });
130 | }
131 |
132 | module.exports = function (options) {
133 | const opts = options || {};
134 | let waitForAssets;
135 | let additionalStreams;
136 |
137 | pluginOptions = opts;
138 | transforms = Array.prototype.slice.call(arguments, 1);
139 |
140 | // If any external streams were included, add matched files to src
141 | if (opts.additionalStreams) {
142 | additionalStreams = handleAdditionalStreams(opts.additionalStreams);
143 |
144 | // If we have additional streams, wait for them to run before continuing
145 | waitForAssets = es.merge(additionalStreams).pipe(through.obj());
146 | } else {
147 | // Else, create a fake stream
148 | waitForAssets = through.obj();
149 | }
150 |
151 | return through.obj(function (file, enc, cb) {
152 | const self = this;
153 |
154 | waitForAssets.pipe(es.wait(() => {
155 | let output;
156 |
157 | // Cache the file base path relative to the cwd
158 | // Use later when it could be dropped
159 | const _basePath = path.dirname(file.path);
160 |
161 | if (file.isNull()) {
162 | return cb(null, file);
163 | }
164 |
165 | if (file.isStream()) {
166 | return cb(new PluginError('gulp-useref', 'Streaming not supported'));
167 | }
168 |
169 | output = useref(file.contents.toString(), opts);
170 |
171 | addHtmlToStream.call(self, file, output[0]);
172 |
173 | if (!opts.noAssets) {
174 | processAssets.call(self, file, _basePath, output[1]);
175 | }
176 |
177 | return cb();
178 | }));
179 |
180 | // If no external streams were included,
181 | // emit 'end' on the empty stream
182 | if (!additionalStreams) {
183 | waitForAssets.emit('end');
184 | }
185 | }, cb => {
186 | const unprocessed = unprocessedCounter.get();
187 | let fn = () => {};
188 |
189 | end.set(cb);
190 |
191 | if (unprocessed === 0) {
192 | fn = cb;
193 | }
194 |
195 | return fn();
196 | });
197 | };
198 |
--------------------------------------------------------------------------------
/test/mock-all.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | /* global describe, it */
3 |
4 | const should = require('should');
5 | const path = require('path');
6 | const gulp = require('gulp');
7 | const useref = require('../index');
8 | const through = require('through2');
9 | const once = require('async-once');
10 |
11 | describe('bulk files', function () {
12 | this.timeout(5000);
13 |
14 | it('should handle all files', done => {
15 | let seriesFn;
16 | const mockGulpDest = require('mock-gulp-dest')(gulp);
17 |
18 | function bulk() {
19 | return gulp.src('test/fixtures/bulk/useref.*.html')
20 | .pipe(useref())
21 | .pipe(gulp.dest('dest', { cwd: 'test' }));
22 | }
23 |
24 | seriesFn = gulp.series(bulk, once(() => {
25 | mockGulpDest.cwd().should.equal(__dirname);
26 | mockGulpDest.basePath().should.equal(path.join(__dirname, 'dest'));
27 | mockGulpDest.assertDestContains([
28 | 'useref.01.html',
29 | 'useref.02.html',
30 | 'useref.03.html',
31 | 'useref.04.html',
32 | 'useref.05.html',
33 | 'useref.06.html',
34 | 'useref.07.html',
35 | 'useref.08.html',
36 | 'useref.09.html',
37 | 'useref.10.html',
38 | 'useref.11.html',
39 | 'useref.12.html',
40 | 'useref.13.html',
41 | 'useref.14.html',
42 | 'useref.15.html',
43 | 'useref.16.html',
44 | 'useref.17.html',
45 | 'useref.18.html',
46 | 'useref.19.html',
47 | 'useref.20.html',
48 | 'useref.21.html',
49 | 'useref.22.html',
50 | 'useref.23.html',
51 | 'useref.24.html',
52 | 'useref.25.html',
53 | 'useref.26.html',
54 | 'useref.27.html',
55 | 'useref.28.html',
56 | 'useref.29.html',
57 | 'useref.30.html',
58 | 'useref.31.html',
59 | 'useref.32.html',
60 | 'useref.33.html',
61 | 'useref.34.html',
62 | 'useref.35.html',
63 | 'useref.36.html',
64 | 'useref.37.html',
65 | 'useref.38.html',
66 | 'useref.39.html',
67 | 'useref.40.html',
68 | 'useref.41.html',
69 | 'useref.42.html',
70 | 'useref.43.html',
71 | 'useref.44.html',
72 | 'useref.45.html',
73 | 'useref.46.html',
74 | 'useref.47.html',
75 | 'useref.48.html',
76 | 'useref.49.html',
77 | 'useref.50.html',
78 | 'useref.51.html',
79 | 'useref.52.html',
80 | 'useref.53.html',
81 | 'useref.54.html',
82 | 'useref.55.html',
83 | 'useref.01.min.css',
84 | 'useref.02.min.css',
85 | 'useref.03.min.css',
86 | 'useref.04.min.css',
87 | 'useref.05.min.css',
88 | 'useref.06.min.css',
89 | 'useref.07.min.css',
90 | 'useref.08.min.css',
91 | 'useref.09.min.css',
92 | 'useref.10.min.css',
93 | 'useref.11.min.css',
94 | 'useref.12.min.css',
95 | 'useref.13.min.css',
96 | 'useref.14.min.css',
97 | 'useref.15.min.css',
98 | 'useref.16.min.css',
99 | 'useref.17.min.css',
100 | 'useref.18.min.css',
101 | 'useref.19.min.css',
102 | 'useref.20.min.css',
103 | 'useref.21.min.css',
104 | 'useref.22.min.css',
105 | 'useref.23.min.css',
106 | 'useref.24.min.css',
107 | 'useref.25.min.css',
108 | 'useref.26.min.css',
109 | 'useref.27.min.css',
110 | 'useref.28.min.css',
111 | 'useref.29.min.css',
112 | 'useref.30.min.css',
113 | 'useref.31.min.css',
114 | 'useref.32.min.css',
115 | 'useref.33.min.css',
116 | 'useref.34.min.css',
117 | 'useref.35.min.css',
118 | 'useref.36.min.css',
119 | 'useref.37.min.css',
120 | 'useref.38.min.css',
121 | 'useref.39.min.css',
122 | 'useref.40.min.css',
123 | 'useref.41.min.css',
124 | 'useref.42.min.css',
125 | 'useref.43.min.css',
126 | 'useref.44.min.css',
127 | 'useref.45.min.css',
128 | 'useref.46.min.css',
129 | 'useref.47.min.css',
130 | 'useref.48.min.css',
131 | 'useref.49.min.css',
132 | 'useref.50.min.css',
133 | 'useref.51.min.css',
134 | 'useref.52.min.css',
135 | 'useref.53.min.css',
136 | 'useref.54.min.css',
137 | 'useref.55.min.css'
138 | ]);
139 |
140 | done();
141 | }));
142 |
143 | seriesFn();
144 | });
145 |
146 | it('should handle all assets', done => {
147 | let seriesFn;
148 | const mockGulpDest = require('mock-gulp-dest')(gulp);
149 |
150 | function bulk() {
151 | return gulp.src('test/fixtures/bulk/useref.56.html')
152 | .pipe(useref({ noconcat: true }))
153 | .pipe(gulp.dest('dest', { cwd: 'test' }));
154 | }
155 |
156 | seriesFn = gulp.series(bulk, once(() => {
157 | mockGulpDest.cwd().should.equal(__dirname);
158 | mockGulpDest.basePath().should.equal(path.join(__dirname, 'dest'));
159 | mockGulpDest.assertDestContains([
160 | 'useref.56.html',
161 | 'useref.01.css',
162 | 'useref.02.css',
163 | 'useref.03.css',
164 | 'useref.04.css',
165 | 'useref.05.css',
166 | 'useref.06.css',
167 | 'useref.07.css',
168 | 'useref.08.css',
169 | 'useref.09.css',
170 | 'useref.10.css',
171 | 'useref.11.css',
172 | 'useref.12.css',
173 | 'useref.13.css',
174 | 'useref.14.css',
175 | 'useref.15.css',
176 | 'useref.16.css',
177 | 'useref.17.css',
178 | 'useref.18.css',
179 | 'useref.19.css',
180 | 'useref.20.css',
181 | 'useref.21.css',
182 | 'useref.22.css',
183 | 'useref.23.css',
184 | 'useref.24.css',
185 | 'useref.25.css',
186 | 'useref.26.css',
187 | 'useref.27.css',
188 | 'useref.28.css',
189 | 'useref.29.css',
190 | 'useref.30.css',
191 | 'useref.31.css',
192 | 'useref.32.css',
193 | 'useref.33.css',
194 | 'useref.34.css',
195 | 'useref.35.css',
196 | 'useref.36.css',
197 | 'useref.37.css',
198 | 'useref.38.css',
199 | 'useref.39.css',
200 | 'useref.40.css',
201 | 'useref.41.css',
202 | 'useref.42.css',
203 | 'useref.43.css',
204 | 'useref.44.css',
205 | 'useref.45.css',
206 | 'useref.46.css',
207 | 'useref.47.css',
208 | 'useref.48.css',
209 | 'useref.49.css',
210 | 'useref.50.css',
211 | 'useref.51.css',
212 | 'useref.52.css',
213 | 'useref.53.css',
214 | 'useref.54.css',
215 | 'useref.55.css',
216 | 'useref.56.css'
217 | ]);
218 |
219 | done();
220 | }));
221 |
222 | seriesFn();
223 | });
224 |
225 | it('should not end the stream prematurely', done => {
226 | let fileCount = 0;
227 |
228 | gulp.src('test/fixtures/04.html')
229 | .pipe(useref())
230 | .pipe(through.obj({ highWaterMark: 1 }, (newFile, enc, callback) => {
231 | fileCount++;
232 | setTimeout(callback, 750);
233 | }, cb => {
234 | fileCount.should.equal(5);
235 | done();
236 | cb();
237 | }));
238 | });
239 | });
240 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [gulp](https://github.com/gulpjs/gulp)-useref  [](https://coveralls.io/github/jonkemp/gulp-useref?branch=master)
2 |
3 | [](https://nodei.co/npm/gulp-useref/)
4 |
5 | > Parse build blocks in HTML files to replace references to non-optimized scripts or stylesheets with [useref](https://github.com/jonkemp/useref)
6 |
7 | Inspired by the grunt plugin [grunt-useref](https://github.com/pajtai/grunt-useref). It can handle file concatenation but not minification. Files are then passed down the stream. For minification of assets or other modifications, use [gulp-if](https://github.com/robrich/gulp-if) to conditionally handle specific types of assets.
8 |
9 |
10 | ## What's new in 3.0?
11 |
12 | Changes under the hood have made the code more efficient and simplified the API. Since the API has changed, please observe the usage examples below.
13 |
14 | If you get errors like
15 |
16 | TypeError: useref.assets is not a function
17 |
18 | or
19 |
20 | TypeError: $.useref.assets is not a function
21 |
22 | please read the Migration Notes below.
23 |
24 | ## Install
25 |
26 | Install with [npm](https://npmjs.org/package/gulp-useref)
27 |
28 | ```
29 | npm install --save-dev gulp-useref
30 | ```
31 |
32 |
33 | ## Usage
34 |
35 | The following example will parse the build blocks in the HTML, replace them and pass those files through. Assets inside the build blocks will be concatenated and passed through in a stream as well.
36 |
37 | ```js
38 | var gulp = require('gulp'),
39 | useref = require('gulp-useref');
40 |
41 | gulp.task('default', function () {
42 | return gulp.src('app/*.html')
43 | .pipe(useref())
44 | .pipe(gulp.dest('dist'));
45 | });
46 | ```
47 |
48 | With options:
49 |
50 | ```js
51 | var gulp = require('gulp'),
52 | useref = require('gulp-useref');
53 |
54 | gulp.task('default', function () {
55 | return gulp.src('app/*.html')
56 | .pipe(useref({ searchPath: '.tmp' }))
57 | .pipe(gulp.dest('dist'));
58 | });
59 | ```
60 |
61 | If you want to minify your assets or perform some other modification, you can use [gulp-if](https://github.com/robrich/gulp-if) to conditionally handle specific types of assets.
62 |
63 | ```js
64 | var gulp = require('gulp'),
65 | useref = require('gulp-useref'),
66 | gulpif = require('gulp-if'),
67 | uglify = require('gulp-uglify'),
68 | minifyCss = require('gulp-clean-css');
69 |
70 | gulp.task('html', function () {
71 | return gulp.src('app/*.html')
72 | .pipe(useref())
73 | .pipe(gulpif('*.js', uglify()))
74 | .pipe(gulpif('*.css', minifyCss()))
75 | .pipe(gulp.dest('dist'));
76 | });
77 | ```
78 |
79 | Blocks are expressed as:
80 |
81 | ```html
82 |
83 | ... HTML Markup, list of script / link tags.
84 |
85 | ```
86 |
87 | - **type**: either `js`, `css` or `remove`; `remove` will remove the build block entirely without generating a file
88 | - **alternate search path**: (optional) By default the input files are relative to the treated file. Alternate search path allows one to change that. The path can also contain a sequence of paths processed from right to left, using JSON brace array notation e.g ``.
89 | - **path**: the file path of the optimized file, the target output
90 | - **parameters**: extra parameters that should be added to the tag
91 |
92 | An example of this in completed form can be seen below:
93 |
94 | ```html
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | ```
110 |
111 | The resulting HTML would be:
112 |
113 | ```html
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 | ```
123 |
124 | See [useref](https://github.com/jonkemp/useref) for more information.
125 |
126 | ## API
127 |
128 | ### useref(options [, transformStream1 [, transformStream2 [, ... ]]])
129 |
130 | Returns a stream with the asset replaced resulting HTML files as well as the concatenated asset files from the build blocks inside the HTML. Supports all options from [useref](https://github.com/jonkemp/useref).
131 |
132 | ### Transform Streams
133 |
134 | Type: `Stream`
135 | Default: `none`
136 |
137 | Transform assets before concat. For example, to integrate source maps:
138 |
139 | ```js
140 | var gulp = require('gulp'),
141 | sourcemaps = require('gulp-sourcemaps'),
142 | useref = require('gulp-useref'),
143 | lazypipe = require('lazypipe');
144 |
145 | gulp.task('default', function () {
146 | return gulp.src('index.html')
147 | .pipe(useref({}, lazypipe().pipe(sourcemaps.init, { loadMaps: true })))
148 | .pipe(sourcemaps.write('maps'))
149 | .pipe(gulp.dest('dist'));
150 | });
151 | ```
152 |
153 | ### Options
154 |
155 | #### options.searchPath
156 |
157 | Type: `String` or `Array`
158 | Default: `none`
159 |
160 | Specify the location to search for asset files, relative to the current working directory. Can be a string or array of strings.
161 |
162 | #### options.base
163 |
164 | Type: `String`
165 | Default: `process.cwd()`
166 |
167 | Specify the output folder relative to the cwd.
168 |
169 | #### options.noAssets
170 |
171 | Type: `Boolean`
172 | Default: `false`
173 |
174 | Skip assets and only process the HTML files.
175 |
176 | #### options.noconcat
177 |
178 | Type: `Boolean`
179 | Default: `false`
180 |
181 | Skip concatenation and add all assets to the stream instead.
182 |
183 | #### options.newLine
184 |
185 | Type: `String`
186 | Default: `none`
187 |
188 | Add a string that should separate the concatenated files.
189 |
190 | #### options.additionalStreams
191 |
192 | Type: `Array`
193 | Default: `none`
194 |
195 | Use additional streams as sources of assets. Useful for combining gulp-useref with preprocessing tools. For example, to use with TypeScript:
196 |
197 | ```javascript
198 | var ts = require('gulp-typescript');
199 |
200 | // create stream of virtual files
201 | var tsStream = gulp.src('src/**/*.ts')
202 | .pipe(ts());
203 |
204 | gulp.task('default', function () {
205 | // use gulp-useref normally
206 | return gulp.src('src/index.html')
207 | .pipe(useref({ additionalStreams: [tsStream] }))
208 | .pipe(gulp.dest('dist'));
209 | });
210 | ```
211 |
212 | #### options.transformPath
213 |
214 | Type: `Function`
215 | Default: `none`
216 |
217 | Add a transformPath function in case the path needs to be modified before search happens.
218 |
219 | ```js
220 | var gulp = require('gulp'),
221 | useref = require('gulp-useref');
222 |
223 | gulp.task('default', function () {
224 | return gulp.src('app/*.html')
225 | .pipe(useref({
226 | transformPath: function(filePath) {
227 | return filePath.replace('/rootpath','')
228 | }
229 | }))
230 | .pipe(gulp.dest('dist'));
231 | });
232 | ```
233 |
234 | ## Migration from v2 API
235 |
236 | If you upgrade gulp-useref from v2 without changing your gulpfile,
237 | you will get errors like this:
238 |
239 | TypeError: $.useref.assets is not a function
240 |
241 | or
242 |
243 | TypeError: useref.assets is not a function
244 |
245 | For a simple configuration, you can replace this V2 code:
246 |
247 | ```js
248 | var gulp = require('gulp'),
249 | useref = require('gulp-useref');
250 |
251 | gulp.task('default', function () {
252 | var assets = useref.assets();
253 |
254 | return gulp.src('app/*.html')
255 | .pipe(assets)
256 | .pipe(assets.restore())
257 | .pipe(useref())
258 | .pipe(gulp.dest('dist'));
259 | });
260 | ```
261 |
262 | with this V3 code:
263 |
264 | ```js
265 | var gulp = require('gulp'),
266 | useref = require('gulp-useref');
267 |
268 | gulp.task('default', function () {
269 | return gulp.src('app/*.html')
270 | .pipe(useref())
271 | .pipe(gulp.dest('dist'));
272 | });
273 | ```
274 |
275 | If you were previously using useref in a multi-stage pipe,
276 | you may need to rewrite the pipe, since the simplified V3 API
277 | may not allow for its previous usage.
278 |
279 | If the gulpfile you are using came from a generator, (for example,
280 | in JohnPapa's excellent "opinionated" HotTowel generator), it may
281 | be more practical to go back to that generator project to see
282 | whether they have upgraded to the V3 gulp-useref API, rather than
283 | trying to understand their pipe.
284 |
285 |
286 | ## Notes
287 |
288 | * [ClosureCompiler.js](https://github.com/dcodeIO/ClosureCompiler.js) doesn't support Buffers, which means if you want to use [gulp-closure-compiler](https://github.com/sindresorhus/gulp-closure-compiler) you'll have to first write out the `combined.js` to disk. See [this](https://github.com/dcodeIO/ClosureCompiler.js/issues/11) for more information.
289 |
290 |
291 | ## Contributing
292 |
293 | See the [CONTRIBUTING Guidelines](https://github.com/jonkemp/gulp-useref/blob/master/CONTRIBUTING.md)
294 |
295 |
296 | ## License
297 |
298 | MIT © [Jonathan Kemp](http://jonkemp.com)
299 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to gulp-useref
2 |
3 | First, thanks for your initiative to help out! One of the reasons that open
4 | source is so great is because of the eagerness of others to help.
5 |
6 | Please take a moment to review this document in order to make the contribution
7 | process easy and effective for everyone involved.
8 |
9 | Following these guidelines helps to communicate that you respect the time of
10 | the developers managing and developing this open source project. In return,
11 | they should reciprocate that respect in addressing your issue or assessing
12 | patches and features.
13 |
14 |
15 | ## Asking a Question
16 |
17 | Before you ask, do some searching and reading. Check the docs, Google, GitHub,
18 | and StackOverflow. If your question is something that has been answered many
19 | times before, the project maintainers might be tired of repeating themselves.
20 |
21 | Whenever possible, ask your question on a public forum. This allows anyone to
22 | answer and makes the answer available for the next person with the same question.
23 | If all else fails, you might tweet at or email the maintainer(s).
24 |
25 |
26 | ## Using the issue tracker
27 |
28 | The issue tracker is the preferred channel for [bug reports](#bug-reports),
29 | [features requests](#feature-requests) and [submitting pull
30 | requests](#pull-requests), but please respect the following restrictions:
31 |
32 | * Please **do not** use the issue tracker for personal support requests (use
33 | [Stack Overflow](http://stackoverflow.com) or IRC).
34 |
35 | * Please **do not** derail or troll issues. Keep the discussion on topic and
36 | respect the opinions of others.
37 |
38 |
39 | ## Bug reports
40 |
41 | A bug is a _demonstrable problem_ that is caused by the code in the repository.
42 | Good bug reports are extremely helpful - thank you!
43 |
44 | ### Has This Been Asked Before?
45 |
46 | Before you submit a bug report, you should search existing issues. Be sure to
47 | check both currently open issues, as well as issues that are already closed. If
48 | you find an issue that seems to be similar to yours, read through it.
49 |
50 | If this issue is the same as yours, you can comment with additional information
51 | to help the maintainer debug it. Adding a comment will subscribe you to email
52 | notifications, which can be helpful in getting important updates regarding the
53 | issue. If you don't have anything to add but still want to receive email
54 | updates, you can click the "watch" button at the bottom of the comments.
55 |
56 | ### Nope, Hasn't Been Asked Before
57 |
58 | If you can't find anything in the existing issues, don't be shy about filing a
59 | new one.
60 |
61 | You should be sure to include the version the project, as well as versions of
62 | related software. For example, be sure to include the version numbers output by
63 | the commands `node --version` and `npm list`. If you notice that your installed
64 | version is not the latest, use `npm update` and confirm that the issue is still
65 | there.
66 |
67 | Please be as thorough as possible. It helps us address the problem more quickly,
68 | so everyone wins!
69 |
70 | Guidelines for bug reports:
71 |
72 | 1. **Use the GitHub issue search** — check if the issue has already been
73 | reported.
74 |
75 | 2. **Check if the issue has been fixed** — try to reproduce it using the
76 | latest `master` or development branch in the repository.
77 |
78 | 3. **Isolate the problem** — create a [reduced test
79 | case](https://css-tricks.com/reduced-test-cases/) and a live example.
80 |
81 | A good bug report shouldn't leave others needing to chase you up for more
82 | information. Please try to be as detailed as possible in your report. What is
83 | your environment? What steps will reproduce the issue? What browser(s) and OS
84 | experience the problem? What would you expect to be the outcome? All these
85 | details will help people to fix any potential bugs.
86 |
87 | Example:
88 |
89 | > Short and descriptive example bug report title
90 | >
91 | > A summary of the issue and the browser/OS environment in which it occurs. If
92 | > suitable, include the steps required to reproduce the bug.
93 | >
94 | > 1. This is the first step
95 | > 2. This is the second step
96 | > 3. Further steps, etc.
97 | >
98 | > `` - a link to the reduced test case
99 | >
100 | > Any other information you want to share that is relevant to the issue being
101 | > reported. This might include the lines of code that you have identified as
102 | > causing the bug, and potential solutions (and your opinions on their
103 | > merits).
104 |
105 |
106 | ## Feature requests
107 |
108 | Feature requests are welcome. But take a moment to find out whether your idea
109 | fits with the scope and aims of the project. It's up to *you* to make a strong
110 | case to convince the project's developers of the merits of this feature. Please
111 | provide as much detail and context as possible.
112 |
113 |
114 | ## Pull requests
115 |
116 | Good pull requests - patches, improvements, new features - are a fantastic
117 | help. They should remain focused in scope and avoid containing unrelated
118 | commits.
119 |
120 | **Please ask first** before embarking on any significant pull request (e.g.
121 | implementing features, refactoring code, porting to a different language),
122 | otherwise you risk spending a lot of time working on something that the
123 | project's developers might not want to merge into the project.
124 |
125 | Before you set out to improve the code, you should have a focused idea in mind
126 | of what you want to do.
127 |
128 | Each commit should do one thing, and each PR should be one specific improvement.
129 |
130 | Please adhere to the coding conventions used throughout a project (indentation,
131 | accurate comments, etc.) and any other requirements (such as test coverage).
132 |
133 | Follow this process if you'd like your work considered for inclusion in the
134 | project:
135 |
136 | 1. [Fork](http://help.github.com/fork-a-repo/) the project, clone your fork,
137 | and configure the remotes:
138 |
139 | ```bash
140 | # Clone your fork of the repo into the current directory
141 | $ git clone https://github.com//gulp-useref
142 | # Navigate to the newly cloned directory
143 | $ cd gulp-useref
144 | # Assign the original repo to a remote called "upstream"
145 | $ git remote add upstream https://github.com/jonkemp/gulp-useref
146 | ```
147 |
148 | 2. If you cloned a while ago, get the latest changes from upstream:
149 |
150 | ```bash
151 | $ git checkout
152 | $ git pull upstream
153 | ```
154 |
155 | 3. Create a new topic branch (off the main project development branch) to
156 | contain your feature, change, or fix:
157 |
158 | ```bash
159 | $ git checkout -b
160 | ```
161 |
162 | 4. Add relevant tests to cover the change.
163 |
164 | 5. Make sure test-suite passes: `npm test`
165 |
166 | 6. Commit your changes in logical chunks. Please adhere to these [git commit
167 | message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
168 | or your code is unlikely be merged into the main project. Use Git's
169 | [interactive rebase](https://help.github.com/articles/interactive-rebase)
170 | feature to tidy up your commits before making them public.
171 |
172 | 7. Locally merge (or rebase) the upstream development branch into your topic branch:
173 |
174 | ```bash
175 | $ git pull [--rebase] upstream
176 | ```
177 |
178 | 8. Push your topic branch up to your fork:
179 |
180 | ```bash
181 | $ git push origin
182 | ```
183 |
184 | 9. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/)
185 | with a clear title and description.
186 |
187 | ## Conventions of commit messages
188 |
189 | Addding files on repo
190 |
191 | ```bash
192 | $ git commit -m "Add filename"
193 | ```
194 |
195 | Updating files on repo
196 |
197 | ```bash
198 | $ git commit -m "Update filename, filename2, filename3"
199 | ```
200 |
201 | Removing files on repo
202 |
203 | ```bash
204 | $ git commit -m "Remove filename"
205 | ```
206 |
207 | Renaming files on repo
208 |
209 | ```bash
210 | $ git commit -m "Rename filename"
211 | ```
212 |
213 | Fixing errors and issues on repo
214 |
215 | ```bash
216 | $ git commit -m "Fixed #issuenumber Message about this fix"
217 | ```
218 |
219 | Adding features on repo
220 |
221 | ```bash
222 | $ git commit -m "Add Feature: nameoffeature Message about this feature"
223 | ```
224 |
225 | Updating features on repo
226 |
227 | ```bash
228 | $ git commit -m "Update Feature: nameoffeature Message about this update"
229 | ```
230 |
231 | Removing features on repo
232 |
233 | ```bash
234 | $ git commit -m "Remove Feature: nameoffeature Message about this"
235 | ```
236 |
237 | Ignoring Travis CI build on repo
238 |
239 | ```bash
240 | $ git commit -m "Commit message here [ci-skip]"
241 | ```
242 |
243 | **IMPORTANT**: By submitting a patch, you agree to allow the project owner to
244 | license your work under the same license as that used by the project.
245 |
246 |
247 | ## Etiquette
248 |
249 | ### Assume Everyone is Doing Their Best
250 |
251 | Project maintainers are busy, so give them some time. Developers involved in
252 | open source often contribute to many projects. It's not uncommon for a developer
253 | to receive dozens of issues notifications a day, so be patient. Maybe the
254 | maintainer has other important things in their life that they need to address.
255 | Prioritizing those things over something on GitHub doesn't make someone lazy.
256 | The health, happiness, and wellbeing of the real person on the other end of the
257 | internet is much more important than any bug.
258 |
259 | One of the strengths of open source is that you can always fork and fix problems
260 | yourself.
261 |
262 |
263 | ## Conclusion
264 |
265 | Thanks for taking the time to read this! Contributions are welcome. Hopefully,
266 | this guide will help make good contributions easier and ultimately, everyone
267 | benefits.
268 |
--------------------------------------------------------------------------------
/test/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | /* global describe, it */
3 | const should = require('should');
4 | const fs = require('fs');
5 | const path = require('path');
6 | const Vinyl = require('vinyl');
7 | const es = require('event-stream');
8 | const useref = require('../index');
9 | const gulp = require('gulp');
10 | const rename = require('gulp-rename');
11 | const through = require('through2');
12 |
13 | function getFile(filePath) {
14 | return new Vinyl({
15 | path: filePath,
16 | cwd: __dirname,
17 | base: path.dirname(filePath),
18 | contents: fs.readFileSync(filePath)
19 | });
20 | }
21 |
22 | function getFixture(filePath) {
23 | return getFile(path.join('test', 'fixtures', filePath));
24 | }
25 |
26 | function getExpected(filePath) {
27 | return getFile(path.join('test', 'expected', filePath));
28 | }
29 |
30 | function compare(name, expectedName, done) {
31 | const stream = useref({ noAssets: true });
32 |
33 | stream.on('data', newFile => {
34 | if (path.basename(newFile.path) === name) {
35 | should(String(getExpected(expectedName).contents)).eql(String(newFile.contents));
36 | }
37 | });
38 |
39 | stream.on('end', () => {
40 | done();
41 | });
42 |
43 | stream.write(getFixture(name));
44 |
45 | stream.end();
46 | }
47 |
48 | describe('useref()', function() {
49 | this.timeout(5000);
50 |
51 | it('file should pass through', done => {
52 | let a = 0;
53 |
54 | const fakeFile = new Vinyl({
55 | path: '/test/fixture/file.js',
56 | cwd: '/test/',
57 | base: '/test/fixture/',
58 | contents: Buffer.from('wadup();')
59 | });
60 |
61 | const stream = useref();
62 | stream.on('data', newFile => {
63 | should.exist(newFile.contents);
64 | newFile.path.should.equal('/test/fixture/file.js');
65 | newFile.relative.should.equal('file.js');
66 | ++a;
67 | });
68 |
69 | stream.once('end', () => {
70 | a.should.equal(1);
71 | done();
72 | });
73 |
74 | stream.write(fakeFile);
75 | stream.end();
76 | });
77 |
78 | it('should let null files pass through', done => {
79 | const stream = useref({ noAssets: true });
80 | let n = 0;
81 |
82 | stream.pipe(es.through(file => {
83 | should.equal(file.path, 'null.md');
84 | should.equal(file.contents, null);
85 | n++;
86 | }, () => {
87 | should.equal(n, 1);
88 | done();
89 | }));
90 |
91 | stream.write(new Vinyl({
92 | path: 'null.md',
93 | contents: null
94 | }));
95 |
96 | stream.end();
97 | });
98 |
99 | it('should emit error on streamed file', done => {
100 | gulp.src(path.join('test', 'fixtures', '01.html'), { buffer: false })
101 | .pipe(useref({ noAssets: true }))
102 | .on('error', ({message}) => {
103 | message.should.equal('Streaming not supported');
104 | done();
105 | });
106 | });
107 |
108 | it('should replace reference in css block and return replaced files', done => {
109 | compare('01.html', '01.html', done);
110 | });
111 |
112 | it('should replace reference in js block and return replaced files', done => {
113 | compare('02.html', '02.html', done);
114 | });
115 |
116 | it('should handle comments and whitespace in blocks', done => {
117 | compare('03.html', '03.html', done);
118 | });
119 |
120 | it('should handle multiple blocks', done => {
121 | compare('04.html', '04.html', done);
122 | });
123 |
124 | it('should handle custom blocks', done => {
125 | const stream = useref({
126 | noAssets: true,
127 | custom(content, target) {
128 | return content === 'someContent' ? target : content;
129 | }
130 | });
131 |
132 | stream.on('data', ({contents}) => {
133 | getExpected('custom-blocks.html').contents.toString().should.equal(contents.toString());
134 | });
135 |
136 | stream.on('end', done);
137 |
138 | stream.write(getFixture('custom-blocks.html'));
139 | stream.end();
140 | });
141 |
142 | it('should concat CSS assets and pass them through', done => {
143 | let a = 0;
144 |
145 | const testFile = getFixture('01.html');
146 |
147 | const stream = useref();
148 |
149 | stream.on('data', newFile => {
150 | should.exist(newFile.contents);
151 | if (a === 1) {
152 | newFile.path.should.equal(path.normalize('./test/fixtures/css/combined.css'));
153 | }
154 | ++a;
155 | });
156 |
157 | stream.once('end', () => {
158 | a.should.equal(2);
159 | done();
160 | });
161 |
162 | stream.write(testFile);
163 |
164 | stream.end();
165 | });
166 |
167 | it('should concat CSS assets with newLine option', done => {
168 | let a = 0;
169 | const testFile = getFixture('01.html');
170 | const separator = '\r\n';
171 | const stream = useref({newLine: separator});
172 | const buffer1 = Buffer.from(fs.readFileSync(path.join('test', 'fixtures', 'css', 'one.css')));
173 | const buffer2 = Buffer.from(separator);
174 | const buffer3 = Buffer.from(fs.readFileSync(path.join('test', 'fixtures', 'css', 'two.css')));
175 | const bufferFinal = Buffer.concat([buffer1, buffer2, buffer3]);
176 | const fileFinal = new Vinyl({ contents: bufferFinal });
177 |
178 | stream.on('data', newFile => {
179 | if (a === 1) {
180 | newFile.path.should.equal(path.normalize('./test/fixtures/css/combined.css'));
181 | newFile.contents.toString().should.equal(fileFinal.contents.toString());
182 | }
183 | ++a;
184 | });
185 |
186 | stream.once('end', () => {
187 | a.should.equal(2);
188 | done();
189 | });
190 |
191 | stream.write(testFile);
192 |
193 | stream.end();
194 | });
195 |
196 | it('should concat CSS assets but skip newLine option if semicolon', done => {
197 | let a = 0;
198 | const testFile = getFixture('01.html');
199 | const separator = ';';
200 | const stream = useref({newLine: separator});
201 | const buffer1 = Buffer.from(fs.readFileSync(path.join('test', 'fixtures', 'css', 'one.css')));
202 | const buffer2 = Buffer.from('\n');
203 | const buffer3 = Buffer.from(fs.readFileSync(path.join('test', 'fixtures', 'css', 'two.css')));
204 | const bufferFinal = Buffer.concat([buffer1, buffer2, buffer3]);
205 | const fileFinal = new Vinyl({ contents: bufferFinal });
206 |
207 | stream.on('data', newFile => {
208 | if (a === 1) {
209 | newFile.path.should.equal(path.normalize('./test/fixtures/css/combined.css'));
210 | newFile.contents.toString().should.equal(fileFinal.contents.toString());
211 | }
212 | ++a;
213 | });
214 |
215 | stream.once('end', () => {
216 | a.should.equal(2);
217 | done();
218 | });
219 |
220 | stream.write(testFile);
221 |
222 | stream.end();
223 | });
224 |
225 | it('should skip concatenation and pass CSS assets through with noconcat option', done => {
226 | let a = 0;
227 |
228 | const testFile = getFixture('01.html');
229 |
230 | const stream = useref({ noconcat: true });
231 |
232 | stream.on('data', newFile => {
233 | should.exist(newFile.contents);
234 |
235 | if (a === 0) {
236 | getExpected('noconcat-css.html').contents.toString().should.equal(newFile.contents.toString());
237 | } else if (a === 1) {
238 | path.normalize(newFile.path).should.equal(path.join(__dirname, './fixtures/css/one.css'));
239 | } else if (a === 2) {
240 | path.normalize(newFile.path).should.equal(path.join(__dirname, './fixtures/css/two.css'));
241 | }
242 | ++a;
243 | });
244 |
245 | stream.once('end', () => {
246 | a.should.equal(3);
247 | done();
248 | });
249 |
250 | stream.write(testFile);
251 |
252 | stream.end();
253 | });
254 |
255 | it('should concat JS assets and pass them through', done => {
256 | let a = 0;
257 |
258 | const testFile = getFixture('02.html');
259 |
260 | const stream = useref();
261 |
262 | stream.on('data', newFile => {
263 | should.exist(newFile.contents);
264 | if (a === 1) {
265 | newFile.path.should.equal(path.normalize('./test/fixtures/scripts/combined.js'));
266 | }
267 | ++a;
268 | });
269 |
270 | stream.once('end', () => {
271 | a.should.equal(2);
272 | done();
273 | });
274 |
275 | stream.write(testFile);
276 |
277 | stream.end();
278 | });
279 |
280 | it('should concat JS assets with newLine option', done => {
281 | let a = 0;
282 | const testFile = getFixture('02.html');
283 | const separator = '\r\n';
284 | const stream = useref({newLine: separator});
285 | const buffer1 = Buffer.from(fs.readFileSync(path.join('test', 'fixtures', 'scripts', 'this.js')));
286 | const buffer2 = Buffer.from(separator);
287 | const buffer3 = Buffer.from(fs.readFileSync(path.join('test', 'fixtures', 'scripts', 'that.js')));
288 | const bufferFinal = Buffer.concat([buffer1, buffer2, buffer3]);
289 | const fileFinal = new Vinyl({ contents: bufferFinal });
290 |
291 | stream.on('data', newFile => {
292 | if (a === 1) {
293 | newFile.path.should.equal(path.normalize('./test/fixtures/scripts/combined.js'));
294 | newFile.contents.toString().should.equal(fileFinal.contents.toString());
295 | }
296 | ++a;
297 | });
298 |
299 | stream.once('end', () => {
300 | a.should.equal(2);
301 | done();
302 | });
303 |
304 | stream.write(testFile);
305 |
306 | stream.end();
307 | });
308 |
309 | it('should concat JS assets with newLine option if semicolon', done => {
310 | let a = 0;
311 | const testFile = getFixture('02.html');
312 | const separator = ';';
313 | const stream = useref({newLine: separator});
314 | const buffer1 = Buffer.from(fs.readFileSync(path.join('test', 'fixtures', 'scripts', 'this.js')));
315 | const buffer2 = Buffer.from(separator);
316 | const buffer3 = Buffer.from(fs.readFileSync(path.join('test', 'fixtures', 'scripts', 'that.js')));
317 | const bufferFinal = Buffer.concat([buffer1, buffer2, buffer3]);
318 | const fileFinal = new Vinyl({ contents: bufferFinal });
319 |
320 | stream.on('data', newFile => {
321 | if (a === 1) {
322 | newFile.path.should.equal(path.normalize('./test/fixtures/scripts/combined.js'));
323 | newFile.contents.toString().should.equal(fileFinal.contents.toString());
324 | }
325 | ++a;
326 | });
327 |
328 | stream.once('end', () => {
329 | a.should.equal(2);
330 | done();
331 | });
332 |
333 | stream.write(testFile);
334 |
335 | stream.end();
336 | });
337 |
338 | it('should skip concatenation and pass JS assets through with noconcat option', done => {
339 | let a = 0;
340 |
341 | const testFile = getFixture('02.html');
342 |
343 | const stream = useref({ noconcat: true });
344 |
345 | stream.on('data', newFile => {
346 | should.exist(newFile.contents);
347 |
348 | if (a === 0) {
349 | getExpected('noconcat-js.html').contents.toString().should.equal(newFile.contents.toString());
350 | } else if (a === 1) {
351 | path.normalize(newFile.path).should.equal(path.join(__dirname, './fixtures/scripts/this.js'));
352 | } else if (a === 2) {
353 | path.normalize(newFile.path).should.equal(path.join(__dirname, './fixtures/scripts/that.js'));
354 | }
355 | ++a;
356 | });
357 |
358 | stream.once('end', () => {
359 | a.should.equal(3);
360 | done();
361 | });
362 |
363 | stream.write(testFile);
364 |
365 | stream.end();
366 | });
367 |
368 | it('should handle an alternate css search path', done => {
369 | let a = 0;
370 |
371 | const testFile = getFixture('05.html');
372 |
373 | const stream = useref();
374 |
375 | stream.on('data', newFile => {
376 | should.exist(newFile.contents);
377 | if (a === 1) {
378 | newFile.path.should.equal(path.normalize('./test/fixtures/css/combined.css'));
379 | }
380 | ++a;
381 | });
382 |
383 | stream.once('end', () => {
384 | a.should.equal(2);
385 | done();
386 | });
387 |
388 | stream.write(testFile);
389 |
390 | stream.end();
391 | });
392 |
393 | it('should handle an alternate js search path', done => {
394 | let a = 0;
395 |
396 | const testFile = getFixture('06.html');
397 |
398 | const stream = useref();
399 |
400 | stream.on('data', newFile => {
401 | should.exist(newFile.contents);
402 | if (a === 1) {
403 | newFile.path.should.equal(path.normalize('./test/fixtures/scripts/combined.js'));
404 | }
405 | ++a;
406 | });
407 |
408 | stream.once('end', () => {
409 | a.should.equal(2);
410 | done();
411 | });
412 |
413 | stream.write(testFile);
414 |
415 | stream.end();
416 | });
417 |
418 | it('should handle an alternate js search path with file separator', done => {
419 | let a = 0;
420 |
421 | const testFile = getFixture('12.html');
422 |
423 | const stream = useref();
424 |
425 | stream.on('data', newFile => {
426 | should.exist(newFile.contents);
427 | if (a === 1) {
428 | newFile.path.should.equal(path.normalize('./test/fixtures/scripts/combined.js'));
429 | }
430 | ++a;
431 | });
432 |
433 | stream.once('end', () => {
434 | a.should.equal(2);
435 | done();
436 | });
437 |
438 | stream.write(testFile);
439 |
440 | stream.end();
441 | });
442 |
443 | it('should get the alternate search path from options via string', done => {
444 | let a = 0;
445 |
446 | const testFile = getFixture('07.html');
447 |
448 | const stream = useref({
449 | searchPath: '.tmp'
450 | });
451 |
452 | stream.on('data', newFile => {
453 | should.exist(newFile.contents);
454 | switch (newFile.path) {
455 | case path.normalize('./test/fixtures/scripts/main.js'):
456 | newFile.path.should.equal(path.normalize('./test/fixtures/scripts/main.js'));
457 | break;
458 | case path.normalize('./test/fixtures/css/combined.css'):
459 | newFile.path.should.equal(path.normalize('./test/fixtures/css/combined.css'));
460 | break;
461 | }
462 | ++a;
463 | });
464 |
465 | stream.once('end', () => {
466 | a.should.equal(3);
467 | done();
468 | });
469 |
470 | stream.write(testFile);
471 |
472 | stream.end();
473 | });
474 |
475 | it('should get the alternate search path from options via array', done => {
476 | let a = 0;
477 |
478 | const testFile = getFixture('07.html');
479 |
480 | const stream = useref({
481 | searchPath: ['.tmp']
482 | });
483 |
484 | stream.on('data', newFile => {
485 | should.exist(newFile.contents);
486 | switch (newFile.path) {
487 | case path.normalize('./test/fixtures/scripts/main.js'):
488 | newFile.path.should.equal(path.normalize('./test/fixtures/scripts/main.js'));
489 | break;
490 | case path.normalize('./test/fixtures/css/combined.css'):
491 | newFile.path.should.equal(path.normalize('./test/fixtures/css/combined.css'));
492 | break;
493 | }
494 | ++a;
495 | });
496 |
497 | stream.once('end', () => {
498 | a.should.equal(3);
499 | done();
500 | });
501 |
502 | stream.write(testFile);
503 |
504 | stream.end();
505 | });
506 |
507 | it('should get the alternate search paths from options via array', done => {
508 | let a = 0;
509 |
510 | const testFile = getFixture('alternate-search-paths.html');
511 |
512 | const stream = useref({
513 | searchPath: ['.tmp', 'fixtures']
514 | });
515 |
516 | stream.on('data', newFile => {
517 | should.exist(newFile.contents);
518 | switch (newFile.path) {
519 | case path.normalize('./test/fixtures/scripts/main.js'):
520 | newFile.path.should.equal(path.normalize('./test/fixtures/scripts/main.js'));
521 | break;
522 | case path.normalize('./test/fixtures/css/combined.css'):
523 | newFile.path.should.equal(path.normalize('./test/fixtures/css/combined.css'));
524 | break;
525 | }
526 | ++a;
527 | });
528 |
529 | stream.once('end', () => {
530 | a.should.equal(3);
531 | done();
532 | });
533 |
534 | stream.write(testFile);
535 |
536 | stream.end();
537 | });
538 |
539 | it('should get the alternate search paths from options with brace expansion', done => {
540 | let a = 0;
541 |
542 | const testFile = getFixture('alternate-search-paths.html');
543 |
544 | const stream = useref({
545 | searchPath: '{.tmp,fixtures}'
546 | });
547 |
548 | stream.on('data', newFile => {
549 | should.exist(newFile.contents);
550 | switch (newFile.path) {
551 | case path.normalize('./test/fixtures/scripts/main.js'):
552 | newFile.path.should.equal(path.normalize('./test/fixtures/scripts/main.js'));
553 | break;
554 | case path.normalize('./test/fixtures/css/combined.css'):
555 | newFile.path.should.equal(path.normalize('./test/fixtures/css/combined.css'));
556 | break;
557 | }
558 | ++a;
559 | });
560 |
561 | stream.once('end', () => {
562 | a.should.equal(3);
563 | done();
564 | });
565 |
566 | stream.write(testFile);
567 |
568 | stream.end();
569 | });
570 |
571 | it('should get assets with parent directory reference using brace expansion', done => {
572 | let a = 0;
573 |
574 | const testFile = getFixture('07.html');
575 |
576 | const stream = useref({
577 | searchPath: '{.{,t{,m}}p,../another/search/path}'
578 | });
579 |
580 | stream.on('data', newFile => {
581 | should.exist(newFile.contents);
582 | switch (newFile.path) {
583 | case path.normalize('./test/fixtures/scripts/main.js'):
584 | newFile.path.should.equal(path.normalize('./test/fixtures/scripts/main.js'));
585 | break;
586 | case path.normalize('./test/fixtures/css/combined.css'):
587 | newFile.path.should.equal(path.normalize('./test/fixtures/css/combined.css'));
588 | break;
589 | }
590 | ++a;
591 | });
592 |
593 | stream.once('end', () => {
594 | a.should.equal(3);
595 | done();
596 | });
597 |
598 | stream.write(testFile);
599 |
600 | stream.end();
601 | });
602 |
603 | it('should handle an alternate search path in multiple build blocks', done => {
604 | let a = 0;
605 |
606 | const testFile = getFixture('08.html');
607 |
608 | const stream = useref();
609 |
610 | stream.on('data', newFile => {
611 | const assetpath = [
612 | './test/fixtures/css/combined.css',
613 | './test/fixtures/scripts/combined.min.js',
614 | './test/fixtures/scripts/combined2.min.js'
615 | ];
616 |
617 | assetpath.forEach(filepath => {
618 | if (newFile.path === path.normalize(filepath)) {
619 | should.exist(newFile.contents);
620 | newFile.path.should.equal(path.normalize(filepath));
621 | ++a;
622 | }
623 | });
624 | });
625 |
626 | stream.once('end', () => {
627 | a.should.equal(3);
628 | done();
629 | });
630 |
631 | stream.write(testFile);
632 |
633 | stream.end();
634 | });
635 |
636 | it('should ignore build blocks with no assets', done => {
637 | let a = 0;
638 |
639 | const testFile = getFixture('09.html');
640 |
641 | const stream = useref();
642 |
643 | stream.on('data', newFile => {
644 | should.exist(newFile.contents);
645 | newFile.path.should.not.equal(path.normalize('./test/fixtures/css/vendor.css'));
646 | ++a;
647 | });
648 |
649 | stream.once('end', () => {
650 | a.should.equal(1);
651 | done();
652 | });
653 |
654 | stream.write(testFile);
655 |
656 | stream.end();
657 | });
658 |
659 | it('should understand absolute search paths', done => {
660 | let a = 0;
661 |
662 | const testFile = getFixture('absolute-search-path.html');
663 |
664 | const searchPath = path.join(__dirname, 'fixtures', 'css');
665 |
666 | const stream = useref({
667 | searchPath
668 | });
669 |
670 | stream.on('data', newFile => {
671 | should.exist(newFile.contents);
672 | if (a === 1) {
673 | newFile.path.should.equal(path.normalize('./test/fixtures/css/combined.css'));
674 | }
675 | ++a;
676 | });
677 |
678 | stream.once('end', () => {
679 | a.should.equal(2);
680 | done();
681 | });
682 |
683 | stream.write(testFile);
684 |
685 | stream.end();
686 | });
687 |
688 | it('should not explode on custom blocks', done => {
689 | const stream = useref();
690 |
691 | stream.on('end', () => {
692 | done();
693 | });
694 |
695 | stream.resume();
696 |
697 | stream.write(getFixture('custom-blocks.html'));
698 | stream.end();
699 | });
700 |
701 | it('should work with relative paths', done => {
702 | let a = 0;
703 |
704 | const testFile = getFixture('10.html');
705 |
706 | const stream = useref();
707 |
708 | stream.on('data', newFile => {
709 | should.exist(newFile.contents);
710 | if (a === 1) {
711 | path.normalize(newFile.path).should.equal(path.normalize('./test/fixtures/scripts/combined.js'));
712 | }
713 | ++a;
714 | });
715 |
716 | stream.once('end', () => {
717 | a.should.equal(2);
718 | done();
719 | });
720 |
721 | stream.write(testFile);
722 |
723 | stream.end();
724 | });
725 |
726 | it('should ignore absolute urls', done => {
727 | let a = 0;
728 |
729 | const testFile = getFixture('remote-path.html');
730 |
731 | const stream = useref();
732 |
733 | stream.on('data', newFile => {
734 | should.exist(newFile.contents);
735 | if (a === 1) {
736 | path.normalize(newFile.path).should.equal(path.normalize('./test/fixtures/css/combined.css'));
737 | }
738 | ++a;
739 | });
740 |
741 | stream.once('end', () => {
742 | a.should.equal(2);
743 | done();
744 | });
745 |
746 | stream.write(testFile);
747 |
748 | stream.end();
749 | });
750 |
751 | it('should transform paths when transformPath function is set', done => {
752 | let a = 0;
753 |
754 | const testFile = getFixture('bad-path.html');
755 |
756 | const stream = useref({
757 | transformPath(filePath) {
758 | return filePath.replace('/rootpath','');
759 | }
760 | });
761 |
762 | stream.on('data', newFile => {
763 | should.exist(newFile.contents);
764 | if (a === 1) {
765 | path.normalize(newFile.path).should.equal(path.normalize('./test/fixtures/css/combined.css'));
766 | }
767 | ++a;
768 | });
769 |
770 | stream.once('end', () => {
771 | a.should.equal(2);
772 | done();
773 | });
774 |
775 | stream.write(testFile);
776 |
777 | stream.end();
778 | });
779 |
780 | it('should return the assets in the order they were found', done => {
781 | const testOrderFile = getFixture('order.html');
782 |
783 | const stream = useref();
784 |
785 | stream.on('data',newFile => {
786 | if (newFile.path === path.normalize('./test/fixtures/css/ordered.css')) {
787 | should(String(getExpected('css/ordered.css').contents)).eql(String(newFile.contents));
788 |
789 | done();
790 | }
791 | });
792 |
793 | stream.write(testOrderFile);
794 |
795 | stream.end();
796 | });
797 |
798 | it('should output assets to a folder relative to the cwd', done => {
799 | let a = 0;
800 |
801 | const testFile = getFixture('02.html');
802 |
803 | const stream = useref({ base: 'app' });
804 |
805 | stream.on('data', newFile => {
806 | should.exist(newFile.contents);
807 | if (a === 1) {
808 | path.normalize(newFile.path).should.equal(path.normalize('./app/scripts/combined.js'));
809 | }
810 | ++a;
811 | });
812 |
813 | stream.once('end', () => {
814 | a.should.equal(2);
815 | done();
816 | });
817 |
818 | stream.write(testFile);
819 |
820 | stream.end();
821 | });
822 |
823 | it('should find assets relative to the root', done => {
824 | let a = 0;
825 |
826 | const testFile = getFixture(path.join('relative', 'child', 'index.html'));
827 |
828 | const stream = useref();
829 |
830 | stream.on('data', newFile => {
831 | should.exist(newFile.contents);
832 | if (a === 1) {
833 | path.normalize(newFile.path).should.equal(path.normalize('./test/fixtures/relative/styles/bundle.css'));
834 | }
835 | ++a;
836 | });
837 |
838 | stream.once('end', () => {
839 | a.should.equal(2);
840 | done();
841 | });
842 |
843 | stream.write(testFile);
844 |
845 | stream.end();
846 | });
847 |
848 | it('should set file.base when asked', done => {
849 | let a = 0;
850 |
851 | const testFile = getFixture(path.join('templates1', 'component.html'));
852 |
853 | const stream = useref({
854 | searchPath: 'fixtures',
855 | base: 'fixtures'
856 | });
857 |
858 | stream.on('data', newFile => {
859 | should.exist(newFile.contents);
860 | if (a === 1) {
861 | path.normalize(newFile.path).should.equal(path.normalize('./fixtures/css/bundle.css'));
862 | path.normalize(newFile.relative).should.equal(path.normalize('css/bundle.css'));
863 | }
864 | ++a;
865 | });
866 |
867 | stream.once('end', () => {
868 | a.should.equal(2);
869 | done();
870 | });
871 |
872 | stream.write(testFile);
873 |
874 | stream.end();
875 | });
876 |
877 | it('should support external streams', done => {
878 | const extStream1 = gulp.src('test/fixtures/scripts/that.js')
879 | .pipe(rename('renamedthat.js'));
880 |
881 | const extStream2 = gulp.src('test/fixtures/scripts/yetonemore.js')
882 | .pipe(rename('renamedyet.js'));
883 |
884 | let fileCount = 0;
885 |
886 | const assets = useref({
887 | noconcat: true,
888 | additionalStreams: [extStream1, extStream2]
889 | });
890 |
891 | gulp.src('test/fixtures/11.html')
892 | .pipe(assets)
893 | .pipe(through.obj((newFile, enc, callback) => {
894 | const assetpath = [
895 | `${__dirname}/fixtures/11.html`,
896 | `${__dirname}/fixtures/scripts/this.js`,
897 | `${__dirname}/fixtures/scripts/anotherone.js`,
898 | `${__dirname}/fixtures/scripts/renamedthat.js`,
899 | `${__dirname}/fixtures/scripts/renamedyet.js`
900 | ];
901 |
902 | assetpath.forEach(filepath => {
903 | if (newFile.path === path.normalize(filepath)) {
904 | should.exist(newFile.contents);
905 | newFile.path.should.equal(path.normalize(filepath));
906 | fileCount++;
907 | }
908 | });
909 | callback();
910 | }, () => {
911 | fileCount.should.equal(5);
912 | done();
913 | }));
914 | });
915 | });
916 |
917 | describe('on error', () => {
918 | it('should emit an error if one of the assets is not found', done => {
919 | const testNonExistentFile = getFixture('nonexistent.html');
920 | const stream = useref();
921 |
922 | stream.on('error', err => {
923 | err.should.match(/File not found with singular glob/);
924 | done();
925 | });
926 |
927 | stream.write(testNonExistentFile);
928 | stream.end();
929 |
930 | });
931 | });
932 |
--------------------------------------------------------------------------------