├── .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 | [![NPM version](https://img.shields.io/npm/v/extra-watch-webpack-plugin.svg?style=flat)](https://npmjs.org/package/extra-watch-webpack-plugin) [![Build Status](https://travis-ci.org/pigcan/extra-watch-webpack-plugin.svg?branch=master)](https://travis-ci.org/pigcan/extra-watch-webpack-plugin) [![Build status](https://ci.appveyor.com/api/projects/status/2wjjvxjdxb2p18iq/branch/master?svg=true)](https://ci.appveyor.com/project/pigcan/extra-watch-webpack-plugin/branch/master) [![Coverage Status](https://coveralls.io/repos/github/pigcan/extra-watch-webpack-plugin/badge.svg?branch=master)](https://coveralls.io/github/pigcan/extra-watch-webpack-plugin?branch=master) [![Dependency Status](https://david-dm.org/pigcan/extra-watch-webpack-plugin.svg)](https://david-dm.org/pigcan/extra-watch-webpack-plugin) [![Greenkeeper badge](https://badges.greenkeeper.io/pigcan/extra-watch-webpack-plugin.svg)](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 | --------------------------------------------------------------------------------