├── .eslintrc
├── .gitignore
├── .travis.yml
├── HISTORY.md
├── LICENSE
├── README.md
├── appveyor.yml
├── options.json
├── package.json
└── src
├── __tests__
├── InvalidPlugin.js
├── fixtures
│ ├── index.js
│ ├── index.json
│ ├── test.json
│ └── watchDir
│ │ └── test.txt
├── helper.js
└── index.test.js
└── index.js
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "extends": "eslint-config-airbnb/base",
4 | "rules": {
5 | "no-console": [0]
6 | }
7 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (http://nodejs.org/api/addons.html)
33 | lib/
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # Typescript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - 6
4 | - 8
5 | - 10
6 | cache:
7 | directories:
8 | - node_modules
9 | install:
10 | - npm install
11 | - npm prune
12 | after_success:
13 | - npm run ci
14 |
--------------------------------------------------------------------------------
/HISTORY.md:
--------------------------------------------------------------------------------
1 | ## ExtraWatchWebpackPlugin
2 |
3 |
4 | ### 1.0.3
5 |
6 | - fix issue that npmjs.com shows `No readme found!`
7 |
8 | ### 1.0.2
9 |
10 | - remove useless console.log https://github.com/pigcan/extra-watch-webpack-plugin/pull/18
11 |
12 | ### 1.0.1
13 |
14 | - bugfix: compatibility on windows
15 |
16 | ### 1.0.0
17 |
18 | - feat: files support glob patterns. Ref #15
19 | - feat: support webpack 1,2,3,4
20 |
21 | ### 0.2.0
22 |
23 | - options.json is better in base dir
24 | - __test__ files should not compile
25 |
26 | ### 0.1.0
27 |
28 | - first bump
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 pigcan
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | [](https://npmjs.org/package/extra-watch-webpack-plugin) [](https://travis-ci.org/pigcan/extra-watch-webpack-plugin) [](https://ci.appveyor.com/project/pigcan/extra-watch-webpack-plugin/branch/master) [](https://coveralls.io/github/pigcan/extra-watch-webpack-plugin?branch=master) [](https://david-dm.org/pigcan/extra-watch-webpack-plugin) [](https://greenkeeper.io/)
3 |
4 |
5 |
6 |
7 |
8 |
9 |
extra watch webpack plugin
10 |
extra-watch-webpack-plugin would help you to attach extra files or dirs to webpack's watch system
11 |
support webpack@1,2,3,4
12 |
13 |
14 | Install
15 |
16 | ```sh
17 | npm install --save extra-watch-webpack-plugin
18 | ```
19 |
20 | Options
21 |
22 | - `files`: `string` (absolute path or glob pattern) or `array`, default `[]`, attach extra files to webpack's watch system
23 | - `dirs`: `string` or `array`, default `[]`, attach extra dirs to webpack's watch system
24 |
25 | Usage
26 |
27 | ```js
28 | // webpack.config.js
29 | import ExtraWatchWebpackPlugin from 'extra-watch-webpack-plugin';
30 | ......
31 | {
32 | plugins: [
33 | new ExtraWatchWebpackPlugin({
34 | files: [ 'path/to/file', 'src/**/*.json' ],
35 | dirs: [ 'path/to/dir' ],
36 | }),
37 | ],
38 | }
39 | ```
40 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | environment:
2 | matrix:
3 | - nodejs_version: '8'
4 | - nodejs_version: '6'
5 |
6 | install:
7 | - ps: Install-Product node $env:nodejs_version
8 | - set CI=true
9 | - npm -g install npm@5.3
10 | - set PATH=%APPDATA%\npm;%PATH%
11 | - npm install
12 |
13 | test_script:
14 | - node --version
15 | - npm --version
16 | - npm test
17 |
18 | version: '{build}'
19 | build: off
20 |
21 | shallow_clone: true
22 | clone_depth: 1
23 |
24 | matrix:
25 | fast_finish: true
--------------------------------------------------------------------------------
/options.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "object",
3 | "properties": {
4 | "files": {
5 | "type": [ "string", "array" ]
6 | },
7 | "dirs": {
8 | "type": [ "string", "array" ]
9 | }
10 | },
11 | "additionalProperties": false
12 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "extra-watch-webpack-plugin",
3 | "version": "1.0.3",
4 | "description": "extra-watch-webpack-plugin would help you to attach extra files or dirs to webpack's watch system",
5 | "main": "./lib/index.js",
6 | "scripts": {
7 | "ci": "nyc report --reporter=text-lcov | coveralls",
8 | "lint": "eslint --ignore-path .gitignore src --fix ",
9 | "test": "nyc --reporter=lcov --reporter=text ava",
10 | "release": "babel src --out-dir lib --ignore /__tests__/",
11 | "prepublish": "npm run lint && npm run test && npm run release"
12 | },
13 | "ava": {
14 | "files": [
15 | "src/__tests__/index.test.js"
16 | ],
17 | "concurrency": 5,
18 | "require": "babel-register",
19 | "babel": "inherit"
20 | },
21 | "nyc": {
22 | "exclude": [
23 | "node_modules",
24 | "**/__tests__",
25 | "**/lib"
26 | ]
27 | },
28 | "repository": {
29 | "type": "git",
30 | "url": "git+https://github.com/pigcan/extra-watch-webpack-plugin.git"
31 | },
32 | "keywords": [
33 | "webpack",
34 | "webpack-plugin",
35 | "watch"
36 | ],
37 | "author": "pigcan ",
38 | "license": "MIT",
39 | "bugs": {
40 | "url": "https://github.com/pigcan/extra-watch-webpack-plugin/issues"
41 | },
42 | "homepage": "https://github.com/pigcan/extra-watch-webpack-plugin#readme",
43 | "devDependencies": {
44 | "ava": "^0.25.0",
45 | "babel-cli": "^6.26.0",
46 | "babel-core": "^6.26.0",
47 | "babel-eslint": "^8.2.1",
48 | "babel-plugin-add-module-exports": "^0.2.1",
49 | "babel-preset-es2015": "^6.24.1",
50 | "babel-preset-stage-0": "^6.24.1",
51 | "babel-register": "^6.26.0",
52 | "coveralls": "^3.0.0",
53 | "eslint": "^4.17.0",
54 | "eslint-config-airbnb": "^17.0.0",
55 | "eslint-plugin-import": "^2.10.0",
56 | "memory-fs": "^0.4.1",
57 | "nyc": "^11.2.1",
58 | "webpack": "^4.21.0"
59 | },
60 | "babel": {
61 | "presets": [
62 | "es2015",
63 | "stage-0"
64 | ],
65 | "plugins": [
66 | "add-module-exports"
67 | ]
68 | },
69 | "dependencies": {
70 | "glob": "^7.1.2",
71 | "is-glob": "^4.0.0",
72 | "lodash.uniq": "^4.5.0",
73 | "schema-utils": "^1.0.0"
74 | },
75 | "files": [
76 | "lib/",
77 | "options.json",
78 | "README.md"
79 | ]
80 | }
81 |
--------------------------------------------------------------------------------
/src/__tests__/InvalidPlugin.js:
--------------------------------------------------------------------------------
1 | export default class InvalidPlugin {
2 | constructor(cb) {
3 | this.cb = cb;
4 | }
5 |
6 | apply(compiler) {
7 | compiler.hooks.invalid.tap('invalid', (changeFilePath) => {
8 | this.cb(changeFilePath);
9 | });
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/index.js:
--------------------------------------------------------------------------------
1 | console.log(1);
2 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/index.json:
--------------------------------------------------------------------------------
1 | 0
--------------------------------------------------------------------------------
/src/__tests__/fixtures/test.json:
--------------------------------------------------------------------------------
1 | {
2 | "test": 1
3 | }
--------------------------------------------------------------------------------
/src/__tests__/fixtures/watchDir/test.txt:
--------------------------------------------------------------------------------
1 | 0
--------------------------------------------------------------------------------
/src/__tests__/helper.js:
--------------------------------------------------------------------------------
1 | import { join } from 'path';
2 |
3 | import webpack from 'webpack';
4 | import MemoryFileSystem from 'memory-fs'; // eslint-disable-line import/no-extraneous-dependencies
5 |
6 | import ExtraWatchWebpackPlugin from '../index';
7 | import InvalidPlugin from './InvalidPlugin';
8 |
9 | export default function createCompiler(options = {}) {
10 | const { cb = () => {} } = options;
11 | const compiler = webpack({
12 | bail: true,
13 | cache: false,
14 | entry: join(__dirname, 'fixtures', 'index.js'),
15 | output: {
16 | path: join(__dirname, 'fixtures', 'dist'),
17 | filename: '[name].js',
18 | chunkFilename: '[name].js',
19 | },
20 | plugins: [
21 | new ExtraWatchWebpackPlugin({
22 | files: 'src/**/*.json',
23 | dirs: join(__dirname, 'fixtures', 'watchDir'),
24 | }),
25 | new InvalidPlugin(cb),
26 | ],
27 | });
28 | compiler.outputFileSystem = new MemoryFileSystem();
29 | compiler.watch({}, (err) => {
30 | if (err) console.error(err);
31 | });
32 | }
33 |
--------------------------------------------------------------------------------
/src/__tests__/index.test.js:
--------------------------------------------------------------------------------
1 | import test from 'ava'; // eslint-disable-line
2 |
3 | import { writeFileSync } from 'fs';
4 | import { join } from 'path';
5 |
6 | import createCompiler from './helper';
7 |
8 | const jsonPath = join(__dirname, 'fixtures', 'index.json');
9 |
10 | test.after('roll-back', () => {
11 | writeFileSync(jsonPath, '0');
12 | });
13 | test.cb(`watch ${jsonPath}`, (t) => {
14 | const options = {
15 | cb: (changeFilePath) => {
16 | t.is(changeFilePath, jsonPath);
17 | t.end();
18 | },
19 | };
20 | createCompiler(options);
21 | writeFileSync(jsonPath, '1');
22 | });
23 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import validateOptions from 'schema-utils';
2 | import uniq from 'lodash.uniq';
3 | import isGlob from 'is-glob';
4 | import glob from 'glob';
5 |
6 | import { resolve } from 'path';
7 |
8 | function getFileAndContextDeps(compilation, files, dirs, cwd) {
9 | const { fileDependencies, contextDependencies } = compilation;
10 | const isWebpack4 = compilation.hooks;
11 | let fds = isWebpack4 ? [...fileDependencies] : fileDependencies;
12 | let cds = isWebpack4 ? [...contextDependencies] : contextDependencies;
13 |
14 | if (files.length > 0) {
15 | files.forEach((pattern) => {
16 | let f = pattern;
17 | if (isGlob(pattern)) {
18 | f = glob.sync(pattern, {
19 | cwd,
20 | dot: true,
21 | absolute: true,
22 | });
23 | }
24 | fds = fds.concat(f);
25 | });
26 | fds = uniq(fds);
27 | }
28 | if (dirs.length > 0) {
29 | cds = uniq(cds.concat(dirs));
30 | }
31 |
32 | return {
33 | fileDependencies: fds,
34 | contextDependencies: cds,
35 | };
36 | }
37 |
38 | export default class ExtraWatchWebpackPlugin {
39 | static defaults = {
40 | cwd: process.cwd(),
41 | files: [],
42 | dirs: [],
43 | };
44 |
45 | constructor(options = {}) {
46 | validateOptions(require('../options.json'), options, 'ExtraWatchWebpackPlugin'); // eslint-disable-line
47 | this.options = { ...ExtraWatchWebpackPlugin.defaults, ...options };
48 | }
49 |
50 | apply(compiler) {
51 | let { files, dirs } = this.options;
52 | const { cwd } = this.options;
53 | files = typeof files === 'string' ? [files] : files;
54 | dirs = typeof dirs === 'string' ? [dirs] : dirs;
55 | if (compiler.hooks) {
56 | compiler.hooks.afterCompile.tap('after-compile', (compilation) => {
57 | const {
58 | fileDependencies,
59 | contextDependencies,
60 | } = getFileAndContextDeps(compilation, files, dirs, cwd);
61 | if (files.length > 0) {
62 | fileDependencies.forEach((file) => {
63 | compilation.fileDependencies.add(resolve(file));
64 | });
65 | }
66 | if (dirs.length > 0) {
67 | contextDependencies.forEach((context) => {
68 | compilation.contextDependencies.add(context);
69 | });
70 | }
71 | });
72 | } else {
73 | compiler.plugin('after-compile', (compilation, callback) => {
74 | const {
75 | fileDependencies,
76 | contextDependencies,
77 | } = getFileAndContextDeps(compilation, files, dirs, cwd);
78 | if (files.length > 0) {
79 | compilation.fileDependencies = fileDependencies; // eslint-disable-line
80 | }
81 | if (dirs.length > 0) {
82 | compilation.contextDependencies = contextDependencies; // eslint-disable-line
83 | }
84 | callback();
85 | });
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------