├── .editorconfig ├── .eslintrc.js ├── .gitattributes ├── .gitignore ├── .remarkrc.js ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── __mocks__ └── vm.js ├── __tests__ ├── fixtures │ ├── .modernizrrc-broken.json │ ├── .modernizrrc.js │ ├── .modernizrrc.json │ ├── index-1.js │ ├── index.js │ └── modernizr.js └── index.test.js ├── babel.config.js ├── husky.config.js ├── index.js ├── lint-staged.config.js ├── package-lock.json └── package.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # For more information please visit http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | max_line_length = 80 12 | 13 | [*.php] 14 | indent_size = 4 15 | 16 | [*.py] 17 | indent_size = 4 18 | max_line_length = 79 19 | 20 | [*.{xml,xml.dist}] 21 | indent_size = 4 22 | max_line_length = 120 23 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = { 4 | parserOptions: { 5 | sourceType: "script" 6 | }, 7 | extends: [ 8 | "plugin:itgalaxy/node", 9 | "plugin:itgalaxy/esnext", 10 | "plugin:itgalaxy/jest", 11 | "plugin:itgalaxy/markdown" 12 | ], 13 | overrides: [ 14 | { 15 | files: ["**/__tests__/**/*.js", "**/__mocks__/**/*.js"], 16 | parserOptions: { 17 | sourceType: "module" 18 | }, 19 | rules: { 20 | "max-classes-per-file": "off", 21 | "node/no-unsupported-features/es-builtins": "off", 22 | "node/no-unsupported-features/es-syntax": "off", 23 | "node/no-unsupported-features/node-builtins": "off" 24 | } 25 | }, 26 | { 27 | files: ["**/*.md"], 28 | parserOptions: { 29 | ecmaFeatures: { 30 | impliedStrict: true 31 | } 32 | }, 33 | rules: { 34 | strict: "off", 35 | "no-undef": "off", 36 | "no-unused-vars": "off", 37 | "no-process-env": "off", 38 | "no-process-exit": "off", 39 | "no-console": "off", 40 | "import/no-unresolved": "off", 41 | "node/no-unpublished-require": "off", 42 | "id-match": "off" 43 | } 44 | } 45 | ], 46 | root: true 47 | }; 48 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ## GITATTRIBUTES FOR WEB PROJECTS 2 | # 3 | # These settings are for any web project. 4 | # 5 | # Details per file setting: 6 | # text These files should be normalized (i.e. convert CRLF to LF). 7 | # binary These files are binary and should be left untouched. 8 | # 9 | # Note that binary is a macro for -text -diff. 10 | ###################################################################### 11 | 12 | ## AUTO-DETECT 13 | ## Handle line endings automatically for files detected as 14 | ## text and leave all files detected as binary untouched. 15 | ## This will handle all files NOT defined below. 16 | * text=auto 17 | 18 | ## Source code 19 | *.bat text eol=crlf 20 | *.coffee text 21 | *.css text 22 | *.htm text 23 | *.html text 24 | *.inc text 25 | *.ini text 26 | *.js text 27 | *.json text 28 | *.jsx text 29 | *.less text 30 | *.od text 31 | *.onlydata text 32 | *.php text 33 | *.pl text 34 | *.py text 35 | *.rb text 36 | *.sass text 37 | *.scm text 38 | *.scss text 39 | *.sh text eol=lf 40 | *.sql text 41 | *.styl text 42 | *.tag text 43 | *.ts text 44 | *.tsx text 45 | *.xml text 46 | *.xhtml text 47 | 48 | ## Docker 49 | *.dockerignore text 50 | Dockerfile text 51 | 52 | ## Documentation 53 | *.markdown text 54 | *.md text 55 | *.mdwn text 56 | *.mdown text 57 | *.mkd text 58 | *.mkdn text 59 | *.mdtxt text 60 | *.mdtext text 61 | *.txt text 62 | AUTHORS text 63 | CHANGELOG text 64 | CHANGES text 65 | CONTRIBUTING text 66 | COPYING text 67 | copyright text 68 | *COPYRIGHT* text 69 | INSTALL text 70 | license text 71 | LICENSE text 72 | NEWS text 73 | readme text 74 | *README* text 75 | TODO text 76 | 77 | ## Templates 78 | *.dot text 79 | *.ejs text 80 | *.haml text 81 | *.handlebars text 82 | *.hbs text 83 | *.hbt text 84 | *.jade text 85 | *.latte text 86 | *.mustache text 87 | *.njk text 88 | *.phtml text 89 | *.tmpl text 90 | *.tpl text 91 | *.twig text 92 | 93 | ## Linters 94 | .babelrc text 95 | .csslintrc text 96 | .eslintrc text 97 | .htmlhintrc text 98 | .jscsrc text 99 | .jshintrc text 100 | .jshintignore text 101 | .nsprc text 102 | .nvmrc text 103 | .prettierrc text 104 | .remarkrc text 105 | .stylelintrc text 106 | 107 | ## Configs 108 | *.bowerrc text 109 | *.cnf text 110 | *.conf text 111 | *.config text 112 | .browserslistrc text 113 | .editorconfig text 114 | .gitattributes text 115 | .gitconfig text 116 | .gitignore text 117 | .htaccess text 118 | *.npmignore text 119 | *.yaml text 120 | *.yml text 121 | browserslist text 122 | Makefile text 123 | makefile text 124 | 125 | ## Heroku 126 | Procfile text 127 | .slugignore text 128 | 129 | ## Graphics 130 | *.ai binary 131 | *.bmp binary 132 | *.eps binary 133 | *.gif binary 134 | *.ico binary 135 | *.jng binary 136 | *.jp2 binary 137 | *.jpg binary 138 | *.jpeg binary 139 | *.jpx binary 140 | *.jxr binary 141 | *.pdf binary 142 | *.png binary 143 | *.psb binary 144 | *.psd binary 145 | *.svg text 146 | *.svgz binary 147 | *.tif binary 148 | *.tiff binary 149 | *.wbmp binary 150 | *.webp binary 151 | 152 | ## Audio 153 | *.kar binary 154 | *.m4a binary 155 | *.mid binary 156 | *.midi binary 157 | *.mp3 binary 158 | *.ogg binary 159 | *.ra binary 160 | 161 | ## Video 162 | *.3gpp binary 163 | *.3gp binary 164 | *.as binary 165 | *.asf binary 166 | *.asx binary 167 | *.fla binary 168 | *.flv binary 169 | *.m4v binary 170 | *.mng binary 171 | *.mov binary 172 | *.mp4 binary 173 | *.mpeg binary 174 | *.mpg binary 175 | *.ogv binary 176 | *.swc binary 177 | *.swf binary 178 | *.webm binary 179 | 180 | ## Archives 181 | *.7z binary 182 | *.gz binary 183 | *.jar binary 184 | *.rar binary 185 | *.tar binary 186 | *.zip binary 187 | 188 | ## Fonts 189 | *.ttf binary 190 | *.eot binary 191 | *.otf binary 192 | *.woff binary 193 | *.woff2 binary 194 | 195 | ## Executables 196 | *.exe binary 197 | *.pyc binary 198 | 199 | ## Lock files 200 | package-lock.json -diff 201 | yarn.lock -diff 202 | composer.lock -diff 203 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Include your project-specific ignores in this file 2 | # Read about how to use .gitignore: https://help.github.com/articles/ignoring-files 3 | # Useful .gitignore templates: https://github.com/github/gitignore 4 | 5 | # Git files 6 | *.diff 7 | *.orig 8 | *.rej 9 | 10 | # Numerous always-ignore extensions 11 | pids 12 | *.pid 13 | *.seed 14 | *.lock 15 | *.err 16 | *.tmp 17 | *.log* 18 | 19 | # Vim 20 | [._]*.s[a-w][a-z] 21 | [._]s[a-w][a-z] 22 | *.un~ 23 | Session.vim 24 | .netrwhist 25 | *~ 26 | 27 | # Text Editors 28 | .swo 29 | *.swp 30 | *.vi 31 | 32 | # Numerous always-ignore directories 33 | logs 34 | tmp 35 | 36 | # Windows files and directories 37 | Thumbs.db 38 | ehthumbs.db 39 | ehthumbs_vista.db 40 | Image.db 41 | Video.db 42 | TVThumb.db 43 | musicThumbs.db 44 | thumbcache_*.db 45 | 46 | # Mac files and directories 47 | .DS_Store 48 | .AppleDouble 49 | .LSOverride 50 | .Spotlight-V100 51 | .Trashes 52 | .AppleDB 53 | .AppleDesktop 54 | Network Trash Folder 55 | Temporary Items 56 | .apdisk 57 | 58 | # Thumbnails 59 | ._* 60 | 61 | # IntelliJ IDEA and other products 62 | *.iml 63 | .idea 64 | release 65 | 66 | # VSCode metadata 67 | .vscode 68 | 69 | # Sublime 70 | *.sublime-project 71 | *.sublime-workspace 72 | .sublimelinterrc 73 | 74 | # Eclipse 75 | .project 76 | .classpath 77 | .settings 78 | 79 | # gitkeep 80 | !.gitkeep 81 | 82 | # Directory for instrumented libs generated by `jscoverage/JSCover` 83 | lib-cov 84 | 85 | # Coverage directory used by tools like `istanbul`, `phpunit/php-code-coverage` and etc. 86 | coverage 87 | 88 | # Reports 89 | report 90 | 91 | # nyc test coverage 92 | .nyc_output 93 | 94 | # node-waf configuration 95 | .lock-wscript 96 | 97 | # Compiled binary addons (http://nodejs.org/api/addons.html) 98 | build/Release 99 | 100 | # Dependency directories 101 | bower_components 102 | .bower-cache 103 | .bower-registry 104 | .bower-tmp 105 | node_modules 106 | jspm_packages 107 | vendor 108 | 109 | # Optional npm cache directory 110 | .npm 111 | 112 | # Optional REPL history 113 | .node_repl_history 114 | 115 | # Ignore minified files 116 | *.min.* 117 | 118 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 119 | .grunt 120 | 121 | # Python 122 | *.pyc 123 | 124 | # Caches 125 | .cache 126 | .cache-loader 127 | .eslintcache 128 | .eclintercache 129 | .stylelintcache 130 | .sass-cache 131 | .phpcscache 132 | 133 | # npm 134 | npm-shrinkwrap.json 135 | !package-lock.json 136 | 137 | # Yarn 138 | !yarn.lock 139 | 140 | # Advisories 141 | *advisories.json 142 | 143 | # Dotenv 144 | .env 145 | .env.* 146 | !.env*.example 147 | 148 | # jscpd 149 | .jscpd 150 | 151 | # Webpack stats 152 | stats-*.json 153 | 154 | # Composer 155 | composer.phar 156 | !composer.lock 157 | 158 | -------------------------------------------------------------------------------- /.remarkrc.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = { 4 | plugins: ["remark-preset-lint-itgalaxy"] 5 | }; 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | git: 4 | depth: 10 5 | 6 | branches: 7 | only: 8 | - master 9 | - next 10 | 11 | language: node_js 12 | 13 | cache: 14 | directories: 15 | - $HOME/.npm 16 | - node_modules 17 | 18 | matrix: 19 | include: 20 | - node_js: "11" 21 | env: JOB_PART=lint 22 | - node_js: "11" 23 | env: JOB_PART=test:only 24 | - node_js: "10" 25 | env: JOB_PART=test:only 26 | - node_js: "8" 27 | env: JOB_PART=test:only 28 | - node_js: "6" 29 | env: JOB_PART=test:only 30 | 31 | before_install: 32 | - npm install -g npm@latest 33 | 34 | install: 35 | - npm ci 36 | 37 | before_script: 38 | - node --version 39 | - npm --version 40 | 41 | script: 42 | - npm run $JOB_PART 43 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | This project adheres to [Semantic Versioning](http://semver.org). 6 | 7 | ## 5.0.0 - 2019-02-04 8 | 9 | - Changed: drop support for `webpack` < 4 10 | - Changed: drop support for `node` < 6.9 11 | - Chore: minimum required `modernizr` version is now `^3.7.1`. 12 | 13 | ## 4.0.1 - 2018-02-13 14 | 15 | - Build: add `node@9` to travis CI. 16 | - Chore: minimum required `modernizr` version is now `^3.5.0`. 17 | - Chore: support `webpack` v4. 18 | 19 | ## 4.0.0 - 2017-08-25 20 | 21 | - Changed: configuration loading behaviour. See `README.md`. 22 | - Fixed: avoid problem when `Modernizr` already exists. 23 | 24 | ## 3.0.1 - 2017-06-20 25 | 26 | - Chore: support `webpack` v3. 27 | - Refactor: remove unnecessary legacy `webpack` v1 code. 28 | 29 | ## 3.0.0 - 2017-02-27 30 | 31 | - Fixed: minimum required loader-utils version is now `~1.0.0`. 32 | - Removed: support `webpack` version `1`. 33 | 34 | ## 2.0.0 - 2017-02-01 35 | 36 | - Changed: no longer required to transfer options for `modernizr` using `config` option. 37 | - Changed: to load configuration from file, need specify `useConfigFile` option. 38 | - Chore: no need to use function `encodeURI` for `query string`. 39 | 40 | ## 1.0.2 - 2017-01-31 41 | 42 | - Fixed: updated webpack peer dependency to support `2.2.1`. 43 | 44 | ## 1.0.1 45 | 46 | - Fixed: resolved configuration file only if file passed. 47 | 48 | ## 1.0.0 49 | 50 | - Chore: initial public release. 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017-present itgalaxy inc. 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 | # webpack-modernizr-loader 2 | 3 | [![NPM version](https://img.shields.io/npm/v/webpack-modernizr-loader.svg)](https://www.npmjs.org/package/webpack-modernizr-loader) 4 | [![Travis Build Status](https://img.shields.io/travis/itgalaxy/webpack-modernizr-loader/master.svg?label=build)](https://travis-ci.org/itgalaxy/webpack-modernizr-loader) 5 | [![dependencies Status](https://david-dm.org/itgalaxy/webpack-modernizr-loader/status.svg)](https://david-dm.org/itgalaxy/webpack-modernizr-loader) 6 | [![devDependencies Status](https://david-dm.org/itgalaxy/webpack-modernizr-loader/dev-status.svg)](https://david-dm.org/itgalaxy/webpack-modernizr-loader?type=dev) 7 | 8 | Get your modernizr build bundled with webpack. 9 | 10 | ## Installation 11 | 12 | ```shell 13 | $ npm install webpack-modernizr-loader --save-dev 14 | ``` 15 | 16 | ## Usage 17 | 18 | [Documentation: Using loaders](http://webpack.github.io/docs/using-loaders.html) 19 | 20 | There are three use case. 21 | 22 | 1. Using loader `options`. 23 | 24 | ```javascript 25 | const modernizr = require("modernizr"); 26 | ``` 27 | 28 | **webpack.config.js** 29 | 30 | ```javascript 31 | module.exports = { 32 | module: { 33 | rules: [ 34 | { 35 | loader: "webpack-modernizr-loader", 36 | options: { 37 | // Full list of supported options can be found in [config-all.json](https://github.com/Modernizr/Modernizr/blob/master/lib/config-all.json). 38 | options: ["setClasses"], 39 | "feature-detects": [ 40 | "test/css/flexbox", 41 | "test/es6/promises", 42 | "test/serviceworker" 43 | ] 44 | // Uncomment this when you use `JSON` format for configuration 45 | // type: 'javascript/auto' 46 | }, 47 | test: /empty-alias-file\.js$/ 48 | } 49 | ] 50 | }, 51 | resolve: { 52 | alias: { 53 | // You can add comment "Please do not delete this file" in this file 54 | modernizr$: path.resolve(__dirname, "/path/to/empty-alias-file.js") 55 | } 56 | } 57 | }; 58 | ``` 59 | 60 | 2. Using config file through alias (supported **JavaScript** and **JSON** syntax). 61 | 62 | ```javascript 63 | const modernizr = require("modernizr"); 64 | ``` 65 | 66 | **.modernizrrc.js** 67 | 68 | ```javascript 69 | module.exports = { 70 | options: ["setClasses"], 71 | "feature-detects": [ 72 | "test/css/flexbox", 73 | "test/es6/promises", 74 | "test/serviceworker" 75 | ] 76 | }; 77 | ``` 78 | 79 | **webpack.config.js** 80 | 81 | ```javascript 82 | module.exports = { 83 | module: { 84 | rules: [ 85 | { 86 | loader: "webpack-modernizr-loader", 87 | test: /\.modernizrrc\.js$/ 88 | // Uncomment this when you use `JSON` format for configuration 89 | // type: 'javascript/auto' 90 | } 91 | ] 92 | }, 93 | resolve: { 94 | alias: { 95 | modernizr$: path.resolve(__dirname, "/path/to/.modernizrrc.js") 96 | } 97 | } 98 | }; 99 | ``` 100 | 101 | 3. Using config (supported **JavaScript** and **JSON** syntax) file directly (see below example how it is use). 102 | 103 | ```javascript 104 | const modernizr = require("modernizr"); 105 | ``` 106 | 107 | **webpack.config.js** 108 | 109 | ```javascript 110 | module.exports = { 111 | module: { 112 | rules: [ 113 | { 114 | loader: "webpack-modernizr-loader", 115 | test: /\.modernizrrc\.js$/ 116 | // Uncomment this when you use `JSON` format for configuration 117 | // type: 'javascript/auto' 118 | } 119 | ] 120 | } 121 | }; 122 | ``` 123 | 124 | ## Related 125 | 126 | - [Modernizr](https://github.com/Modernizr/Modernizr) - API for this module 127 | 128 | ## Contribution 129 | 130 | Feel free to push your code if you agree with publishing under the MIT license. 131 | 132 | ## [Changelog](CHANGELOG.md) 133 | 134 | ## [License](LICENSE) 135 | -------------------------------------------------------------------------------- /__mocks__/vm.js: -------------------------------------------------------------------------------- 1 | // __mocks__/vm.js 2 | const vm = jest.genMockFromModule("vm"); 3 | 4 | // r.js calls vm.runInThisContext during initialization 5 | // but when running under jest it does not work as expected. 6 | // This assumes nothing else calls this method during the tests... 7 | vm.runInThisContext = function() { 8 | // eslint-disable-next-line no-undefined 9 | return undefined; 10 | }; 11 | 12 | module.exports = vm; 13 | -------------------------------------------------------------------------------- /__tests__/fixtures/.modernizrrc-broken.json: -------------------------------------------------------------------------------- 1 | foo 2 | -------------------------------------------------------------------------------- /__tests__/fixtures/.modernizrrc.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = { 4 | minify: false, 5 | options: ["setClasses"], 6 | "feature-detects": [ 7 | "test/css/cssgrid", 8 | "test/css/flexbox", 9 | "test/es6/promises", 10 | "test/serviceworker" 11 | ] 12 | }; 13 | -------------------------------------------------------------------------------- /__tests__/fixtures/.modernizrrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "minify": false, 3 | "options": [ 4 | "setClasses" 5 | ], 6 | "feature-detects": [ 7 | "test/css/cssgrid", 8 | "test/css/flexbox", 9 | "test/es6/promises", 10 | "test/serviceworker" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /__tests__/fixtures/index-1.js: -------------------------------------------------------------------------------- 1 | require("modernizr"); 2 | -------------------------------------------------------------------------------- /__tests__/fixtures/index.js: -------------------------------------------------------------------------------- 1 | require("./.modernizrrc.json"); 2 | -------------------------------------------------------------------------------- /__tests__/fixtures/modernizr.js: -------------------------------------------------------------------------------- 1 | /* Please do not delete this file */ 2 | -------------------------------------------------------------------------------- /__tests__/index.test.js: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | import path from "path"; 3 | import pify from "pify"; 4 | import tempy from "tempy"; 5 | import webpack from "webpack"; 6 | import modernizrConfigJSONRc from "./fixtures/.modernizrrc.json"; 7 | 8 | const loader = path.resolve(__dirname, "../index.js"); 9 | const fixturesDir = path.resolve(__dirname, "fixtures"); 10 | 11 | // Workaround https://github.com/facebook/jest/issues/1914 12 | jest.mock("vm"); 13 | jest.mock("modernizr", () => ({ 14 | build: (config, callback) => 15 | callback( 16 | "(function(window, document, undefined){windows.Modernizr = 'Mocked value';})(window, document);" 17 | ) 18 | })); 19 | 20 | describe("loader", () => { 21 | it("should execute successfully using config file inside `require`", () => { 22 | const buildDir = tempy.directory(); 23 | const webpackConfig = { 24 | mode: "development", 25 | context: fixturesDir, 26 | entry: "./index.js", 27 | module: { 28 | rules: [ 29 | { 30 | loader, 31 | test: /\.modernizrrc\.json$/, 32 | type: "javascript/auto" 33 | } 34 | ] 35 | }, 36 | output: { 37 | filename: "bundle.js", 38 | path: buildDir 39 | } 40 | }; 41 | 42 | return pify(webpack)(webpackConfig).then(stats => { 43 | expect(stats.compilation.warnings).toHaveLength(0); 44 | expect(stats.compilation.errors).toHaveLength(0); 45 | 46 | return pify(fs) 47 | .readFile(path.join(buildDir, "bundle.js"), "utf8") 48 | .then(data => { 49 | expect(data).toEqual(expect.stringContaining("windows.Modernizr")); 50 | 51 | return Promise.resolve(); 52 | }); 53 | }); 54 | }); 55 | 56 | it("should execute successfully using options and alias with empty file", () => { 57 | const buildDir = tempy.directory(); 58 | const webpackConfig = { 59 | mode: "development", 60 | context: fixturesDir, 61 | entry: "./index-1.js", 62 | module: { 63 | rules: [ 64 | { 65 | loader, 66 | options: modernizrConfigJSONRc, 67 | test: /modernizr\.js$/ 68 | } 69 | ] 70 | }, 71 | output: { 72 | filename: "bundle.js", 73 | path: buildDir 74 | }, 75 | resolve: { 76 | alias: { 77 | modernizr$: `${path.resolve(__dirname, "fixtures/modernizr.js")}` // eslint-disable-line id-match 78 | } 79 | } 80 | }; 81 | 82 | return pify(webpack)(webpackConfig).then(stats => { 83 | expect(stats.compilation.warnings).toHaveLength(0); 84 | expect(stats.compilation.errors).toHaveLength(0); 85 | 86 | return pify(fs) 87 | .readFile(path.join(buildDir, "bundle.js"), "utf8") 88 | .then(data => { 89 | expect(data).toEqual(expect.stringContaining("windows.Modernizr")); 90 | 91 | return Promise.resolve(); 92 | }); 93 | }); 94 | }); 95 | 96 | it("should execute successfully using options and alias with non-empty file", () => { 97 | const buildDir = tempy.directory(); 98 | const webpackConfig = { 99 | mode: "development", 100 | context: fixturesDir, 101 | entry: "./index-1.js", 102 | module: { 103 | rules: [ 104 | { 105 | loader, 106 | options: modernizrConfigJSONRc, 107 | test: /\.modernizrrc\.js$/ 108 | } 109 | ] 110 | }, 111 | output: { 112 | filename: "bundle.js", 113 | path: buildDir 114 | }, 115 | resolve: { 116 | alias: { 117 | modernizr$: `${path.resolve(__dirname, "fixtures/.modernizrrc.js")}` // eslint-disable-line id-match 118 | } 119 | } 120 | }; 121 | 122 | return pify(webpack)(webpackConfig).then(stats => { 123 | expect(stats.compilation.warnings).toHaveLength(0); 124 | expect(stats.compilation.errors).toHaveLength(0); 125 | 126 | return pify(fs) 127 | .readFile(path.join(buildDir, "bundle.js"), "utf8") 128 | .then(data => { 129 | expect(data).toEqual(expect.stringContaining("windows.Modernizr")); 130 | 131 | return Promise.resolve(); 132 | }); 133 | }); 134 | }); 135 | 136 | it("should execute successfully using alias with empty file", () => { 137 | const buildDir = tempy.directory(); 138 | const webpackConfig = { 139 | mode: "development", 140 | context: fixturesDir, 141 | entry: "./index-1.js", 142 | module: { 143 | rules: [ 144 | { 145 | loader, 146 | test: /modernizr\.js$/ 147 | } 148 | ] 149 | }, 150 | output: { 151 | filename: "bundle.js", 152 | path: buildDir 153 | }, 154 | resolve: { 155 | alias: { 156 | modernizr$: `${path.resolve(__dirname, "fixtures/modernizr.js")}` // eslint-disable-line id-match 157 | } 158 | } 159 | }; 160 | 161 | return pify(webpack)(webpackConfig).then(stats => { 162 | expect(stats.compilation.warnings).toHaveLength(0); 163 | expect(stats.compilation.errors).toHaveLength(0); 164 | 165 | return pify(fs) 166 | .readFile(path.join(buildDir, "bundle.js"), "utf8") 167 | .then(data => { 168 | expect(data).toEqual(expect.stringContaining("windows.Modernizr")); 169 | 170 | return Promise.resolve(); 171 | }); 172 | }); 173 | }); 174 | 175 | it("should execute successfully using alias as JSON config file", () => { 176 | const buildDir = tempy.directory(); 177 | const webpackConfig = { 178 | mode: "development", 179 | context: fixturesDir, 180 | entry: "./index-1.js", 181 | module: { 182 | rules: [ 183 | { 184 | loader, 185 | test: /\.modernizrrc\.json$/, 186 | type: "javascript/auto" 187 | } 188 | ] 189 | }, 190 | output: { 191 | filename: "bundle.js", 192 | path: buildDir 193 | }, 194 | resolve: { 195 | alias: { 196 | modernizr$: `${path.resolve(__dirname, "fixtures/.modernizrrc.json")}` // eslint-disable-line id-match 197 | } 198 | } 199 | }; 200 | 201 | return pify(webpack)(webpackConfig).then(stats => { 202 | expect(stats.compilation.warnings).toHaveLength(0); 203 | expect(stats.compilation.errors).toHaveLength(0); 204 | 205 | return pify(fs) 206 | .readFile(path.join(buildDir, "bundle.js"), "utf8") 207 | .then(data => { 208 | expect(data).toEqual(expect.stringContaining("windows.Modernizr")); 209 | 210 | return Promise.resolve(); 211 | }); 212 | }); 213 | }); 214 | 215 | it("should executes successfully using alias as JavaScript config file", () => { 216 | const buildDir = tempy.directory(); 217 | const webpackConfig = { 218 | mode: "development", 219 | context: fixturesDir, 220 | entry: "./index-1.js", 221 | module: { 222 | rules: [ 223 | { 224 | loader, 225 | test: /\.modernizrrc\.js$/ 226 | } 227 | ] 228 | }, 229 | output: { 230 | filename: "bundle.js", 231 | path: buildDir 232 | }, 233 | resolve: { 234 | alias: { 235 | modernizr$: `${path.resolve(__dirname, "fixtures/.modernizrrc.js")}` // eslint-disable-line id-match 236 | } 237 | } 238 | }; 239 | 240 | return pify(webpack)(webpackConfig).then(stats => { 241 | expect(stats.compilation.warnings).toHaveLength(0); 242 | expect(stats.compilation.errors).toHaveLength(0); 243 | 244 | return pify(fs) 245 | .readFile(path.join(buildDir, "bundle.js"), "utf8") 246 | .then(data => { 247 | expect(data).toEqual(expect.stringContaining("windows.Modernizr")); 248 | 249 | return Promise.resolve(); 250 | }); 251 | }); 252 | }); 253 | 254 | it("should throws error on broken JSON config", () => { 255 | const buildDir = tempy.directory(); 256 | const webpackConfig = { 257 | mode: "development", 258 | context: fixturesDir, 259 | entry: "./index-1.js", 260 | module: { 261 | rules: [ 262 | { 263 | loader, 264 | test: /\.modernizrrc-broken\.json$/ 265 | } 266 | ] 267 | }, 268 | output: { 269 | filename: "bundle.js", 270 | path: buildDir 271 | }, 272 | resolve: { 273 | alias: { 274 | // eslint-disable-next-line id-match 275 | modernizr$: `${path.resolve( 276 | __dirname, 277 | "fixtures/.modernizrrc-broken.json" 278 | )}` 279 | } 280 | } 281 | }; 282 | 283 | return pify(webpack)(webpackConfig).then(stats => { 284 | expect(stats.compilation.warnings).toHaveLength(0); 285 | expect(stats.compilation.errors).toHaveLength(1); 286 | 287 | return Promise.resolve(); 288 | }); 289 | }); 290 | }); 291 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const MIN_BABEL_VERSION = 7; 4 | 5 | module.exports = function preset(api) { 6 | api.assertVersion(MIN_BABEL_VERSION); 7 | 8 | // Cache the returned value forever and don't call this function again. 9 | api.cache(true); 10 | 11 | return { 12 | presets: [ 13 | [ 14 | "@babel/preset-env", 15 | { 16 | targets: { 17 | node: "6.9.0" 18 | } 19 | } 20 | ] 21 | ] 22 | }; 23 | }; 24 | -------------------------------------------------------------------------------- /husky.config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = { 4 | hooks: { 5 | "pre-commit": "lint-staged" 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const modernizr = require("modernizr"); 4 | const loaderUtils = require("loader-utils"); 5 | 6 | function wrapOutput(output) { 7 | // Exposing Modernizr as a module. 8 | return `;(function(window){var hadGlobal='Modernizr' in window;var oldGlobal=window.Modernizr;${output}module.exports=window.Modernizr;if(hadGlobal){window.Modernizr=oldGlobal;}else{delete window.Modernizr;}})(window);`; 9 | } 10 | 11 | module.exports = function() { 12 | const callback = this.async(); 13 | const options = loaderUtils.getOptions(this) || {}; 14 | 15 | let userConfig = {}; 16 | 17 | if (Object.keys(options).length === 0) { 18 | try { 19 | // eslint-disable-next-line import/no-dynamic-require, global-require 20 | userConfig = require(this.resource); 21 | } catch (error) { 22 | return callback(error); 23 | } 24 | } else { 25 | userConfig = options; 26 | } 27 | 28 | const config = Object.assign({}, userConfig); 29 | 30 | return modernizr.build(config, output => callback(null, wrapOutput(output))); 31 | }; 32 | -------------------------------------------------------------------------------- /lint-staged.config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = { 4 | "*.{js,mjs,jsx}": [ 5 | "prettier --list-different", 6 | "eslint --report-unused-disable-directives", 7 | "git add" 8 | ], 9 | "*.{md,markdown,mdown,mkdn,mkd,mdwn,mkdown,ron}": [ 10 | "remark -f -q", 11 | "prettier --list-different", 12 | "git add" 13 | ], 14 | "*.{yml,yaml}": ["prettier --list-different", "git add"] 15 | }; 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-modernizr-loader", 3 | "version": "5.0.0", 4 | "description": "Get your modernizr build bundled with webpack, use modernizr with webpack easily", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/itgalaxy/webpack-modernizr-loader.git" 8 | }, 9 | "homepage": "https://github.com/itgalaxy/webpack-modernizr-loader", 10 | "keywords": [ 11 | "modernizr", 12 | "webpack", 13 | "loader" 14 | ], 15 | "author": "itgalaxy ", 16 | "bugs": { 17 | "url": "https://github.com/itgalaxy/webpack-modernizr-loader/issues" 18 | }, 19 | "license": "MIT", 20 | "main": "index.js", 21 | "files": [ 22 | "index.js" 23 | ], 24 | "engines": { 25 | "node": ">= 6.9.0" 26 | }, 27 | "dependencies": { 28 | "loader-utils": "^1.0.0", 29 | "modernizr": "^3.7.1" 30 | }, 31 | "devDependencies": { 32 | "@babel/core": "^7.1.6", 33 | "@babel/preset-env": "^7.1.6", 34 | "babel-eslint": "^10.0.1", 35 | "babel-jest": "^24.1.0", 36 | "eslint": "^5.15.0", 37 | "eslint-plugin-ava": "^5.1.1", 38 | "eslint-plugin-html": "^5.0.3", 39 | "eslint-plugin-import": "^2.6.0", 40 | "eslint-plugin-itgalaxy": "^98.0.0", 41 | "eslint-plugin-jest": "^22.3.0", 42 | "eslint-plugin-jsx-a11y": "^6.0.0", 43 | "eslint-plugin-lodash": "^5.1.0", 44 | "eslint-plugin-markdown": "^1.0.0", 45 | "eslint-plugin-node": "^8.0.1", 46 | "eslint-plugin-promise": "^4.0.1", 47 | "eslint-plugin-react": "^7.1.0", 48 | "eslint-plugin-unicorn": "^7.1.0", 49 | "husky": "^1.3.1", 50 | "jest": "^24.1.0", 51 | "lint-staged": "^8.1.5", 52 | "npm-run-all": "^4.0.0", 53 | "npmpub": "^4.1.0", 54 | "pify": "^4.0.1", 55 | "prettier": "^1.5.2", 56 | "remark-cli": "^6.0.1", 57 | "remark-preset-lint-itgalaxy": "^14.0.0", 58 | "tempy": "^0.2.0", 59 | "webpack": "^4.29.6" 60 | }, 61 | "peerDependencies": { 62 | "webpack": "^4.0.0" 63 | }, 64 | "scripts": { 65 | "lint:prettier": "prettier --list-different 'test/**/*.{js,md,yml}' '*.{js,md,yml}'", 66 | "lint:js": "eslint . --cache --report-unused-disable-directives --ignore-path .gitignore --ext 'js,.mjs,.md'", 67 | "lint:md": "remark . -i .gitignore -f -q", 68 | "lint": "npm-run-all -l -p lint:**", 69 | "prettify": "npm run lint:prettier -- --write", 70 | "fix:js": "npm run lint:js -- --fix", 71 | "fix": "npm-run-all -l prettify -p 'fix:**'", 72 | "pretest": "npm run lint", 73 | "test:only": "jest --testPathIgnorePatterns=fixtures", 74 | "test": "npm run test:only", 75 | "release": "npmpub" 76 | } 77 | } 78 | --------------------------------------------------------------------------------