├── .npmignore ├── .github └── workflows │ └── ci.yml ├── index.js ├── .gitignore ├── package.json ├── README.md ├── LICENSE └── test └── test.js /.npmignore: -------------------------------------------------------------------------------- 1 | # Everything 2 | * 3 | 4 | !index.js 5 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | tags: 8 | - v*.*.* 9 | pull_request: 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v1 16 | - uses: actions/setup-node@v1 17 | with: 18 | node-version: '12.x' 19 | registry-url: 'https://registry.npmjs.org' 20 | - run: npm install 21 | - run: npm test 22 | - run: npm publish 23 | if: startsWith(github.ref, 'refs/tags/') 24 | env: 25 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 26 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tobias Koppers @sokra 3 | * @author Erik Desjardins 4 | * See LICENSE file in root directory for full license. 5 | */ 6 | 7 | 'use strict'; 8 | 9 | module.exports = function(source) { 10 | var value = typeof source === 'string' ? JSON.parse(source) : source; 11 | var path = this.query ? this.query.slice(1).split('.') : []; 12 | var prop = path.reduce(function(obj, key) { 13 | if (!(key in obj)) throw new Error('Property "' + path.join('.') + '" not found'); 14 | return obj[key] 15 | }, value); 16 | return 'module.exports = ' + JSON.stringify(prop) + ';'; 17 | }; 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 18 | .grunt 19 | 20 | # node-waf configuration 21 | .lock-wscript 22 | 23 | # Compiled binary addons (http://nodejs.org/api/addons.html) 24 | build/Release 25 | 26 | # Dependency directory 27 | node_modules 28 | 29 | # Optional npm cache directory 30 | .npm 31 | 32 | # Optional REPL history 33 | .node_repl_history 34 | 35 | # IntelliJ 36 | *.iml 37 | .idea 38 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "prop-loader", 3 | "version": "1.0.0", 4 | "description": "Webpack loader to extract properties from JSON.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "ava test/test.js" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/erikdesjardins/prop-loader.git" 12 | }, 13 | "keywords": [ 14 | "webpack" 15 | ], 16 | "author": "Erik Desjardins", 17 | "license": "MIT", 18 | "bugs": { 19 | "url": "https://github.com/erikdesjardins/prop-loader/issues" 20 | }, 21 | "homepage": "https://github.com/erikdesjardins/prop-loader#readme", 22 | "peerDependencies": { 23 | "webpack": ">=2.2.0" 24 | }, 25 | "devDependencies": { 26 | "ava": "^2.4.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # prop-loader 2 | 3 | Webpack loader to extract properties from JSON. 4 | 5 | Based on [`json-loader`](https://github.com/webpack/json-loader). 6 | 7 | ## Installation 8 | 9 | `npm install --save-dev prop-loader` 10 | 11 | ## Usage 12 | 13 | **manifest.json:** 14 | 15 | ```json 16 | { 17 | "version": "1.2.3", 18 | "background": { 19 | "scripts": ["background.js"] 20 | } 21 | } 22 | ``` 23 | 24 | **example.js:** 25 | 26 | ```js 27 | var everything = require('prop-loader!manifest.json'); 28 | // everything === { "version": "1.2.3", "background": { "scripts": ["background.js"] } } 29 | 30 | var version = require('prop-loader?version!manifest.json') 31 | // version === "1.2.3"; 32 | 33 | var scripts = require('prop-loader?background.scripts!manifest.json') 34 | // scripts === ["background.js"] 35 | ``` 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Tobias Koppers @sokra 4 | Copyright (c) 2016 Erik Desjardins 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import loader from '../index.js'; 3 | 4 | const json = JSON.stringify({ 5 | version: '1.2.3', 6 | background: { 7 | scripts: ['background.js'] 8 | }, 9 | nil: null 10 | }); 11 | 12 | test('no query', t => { 13 | t.is(loader.call({}, json), 'module.exports = {"version":"1.2.3","background":{"scripts":["background.js"]},"nil":null};'); 14 | }); 15 | 16 | test('single property query', t => { 17 | t.is(loader.call({ query: '?version' }, json), 'module.exports = "1.2.3";'); 18 | }); 19 | 20 | test('deep query', t => { 21 | t.is(loader.call({ query: '?background.scripts' }, json), 'module.exports = ["background.js"];'); 22 | }); 23 | 24 | test('null-valued property', t => { 25 | t.is(loader.call({ query: '?nil' }, json), 'module.exports = null;'); 26 | }); 27 | 28 | test('fails on invalid json', t => { 29 | t.throws(() => loader.call({}, '{'), /Unexpected end of (JSON )?input/); 30 | }); 31 | 32 | test('fails on empty query', t => { 33 | t.throws(() => loader.call({ query: '?' }, json), 'Property "" not found'); 34 | }); 35 | 36 | test('fails on non-existent property', t => { 37 | t.throws(() => loader.call({ query: '?notARealProperty' }, json), 'Property "notARealProperty" not found'); 38 | }); 39 | 40 | test('fails on non-existent deep property', t => { 41 | t.throws(() => loader.call({ query: '?background.foobar' }, json), 'Property "background.foobar" not found'); 42 | }); 43 | 44 | test('passing a js object', t => { 45 | const result = loader.call({ query: '?a.b.c' }, { a: { b: { c: { d: ['e'] } } } }); 46 | t.is(result, 'module.exports = {"d":["e"]};'); 47 | }); 48 | 49 | test('null, no query', t => { 50 | t.is(loader.call({}, null), 'module.exports = null;'); 51 | }); 52 | 53 | test('fails on null with query', t => { 54 | t.throws(() => loader.call({ query: '?prop' }, null), "Cannot use 'in' operator to search for 'prop' in null"); 55 | }); 56 | --------------------------------------------------------------------------------