├── .gitignore ├── .npmignore ├── package.json ├── LICENSE ├── README.md └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .idea -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .gitignore 2 | .npmignore 3 | 4 | .idea 5 | test -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "uglify-loader", 3 | "version": "3.0.0", 4 | "description": "Uglify.js loader for webpack", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/bestander/uglify-loader" 12 | }, 13 | "keywords": [ 14 | "webpack", 15 | "loader" 16 | ], 17 | "author": "Konstantin Raev", 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/bestander/uglify-loader/issues" 21 | }, 22 | "homepage": "https://github.com/bestander/uglify-loader", 23 | "dependencies": { 24 | "loader-utils": "^1.1.0", 25 | "source-map": "^0.7.3", 26 | "uglify-js": "^3.4.8" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Konstantin Raev 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 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # uglify-loader 2 | Uglify loader for webpack 3 | 4 | To install 5 | --- 6 | 7 | ``` 8 | npm install uglify-loader --save-dev 9 | ``` 10 | 11 | Use Case 12 | --- 13 | Webpack has UglifyJSPlugin that uglifies the output after bundling. 14 | In the applications that depend on thirdparty libraries you may want to uglify with mangling only your application code but not the code that you don't control. 15 | 16 | Example 17 | --- 18 | **Webpack 1** 19 | ``` 20 | module: { 21 | loaders: [ 22 | { 23 | // I want to uglify with mangling only app files, not thirdparty libs 24 | test: /.*\/app\/.*\.js$/, 25 | exclude: /.spec.js/, // excluding .spec files 26 | loader: "uglify" 27 | } 28 | ] 29 | } 30 | ``` 31 | 32 | You can pass UglifyJS parameters via 'uglify-loader' property of webpack config. 33 | 34 | ``` 35 | module: { 36 | loaders: [ 37 | { 38 | // I want to uglify with mangling only app files, not thirdparty libs 39 | test: /.*\/app\/.*\.js$/, 40 | exclude: /.spec.js/, // excluding .spec files 41 | loader: "uglify" 42 | } 43 | ] 44 | }, 45 | 'uglify-loader': { 46 | mangle: false 47 | } 48 | ``` 49 | 50 |
51 | 52 | **Webpack 2** 53 | ``` 54 | module: { 55 | rules: [ 56 | { 57 | // I want to uglify with mangling only app files, not thirdparty libs 58 | test: /.*\/app\/.*\.js$/, 59 | exclude: /.spec.js/, // excluding .spec files 60 | use: 'uglify-loader' 61 | } 62 | ] 63 | } 64 | ``` 65 | 66 | You can pass UglifyJS parameters via loader options. 67 | 68 | ``` 69 | module: { 70 | rules: [ 71 | { 72 | // I want to uglify with mangling only app files, not thirdparty libs 73 | test: /.*\/app\/.*\.js$/, 74 | exclude: /.spec.js/, // excluding .spec files 75 | use: { 76 | loader: 'uglify-loader', 77 | options: { 78 | mangle: false 79 | } 80 | } 81 | } 82 | ] 83 | } 84 | ``` 85 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var UglifyJS = require("uglify-js"); 2 | var loaderUtils = require('loader-utils'); 3 | var sourceMap = require('source-map'); 4 | 5 | function mergeSourceMap(map, inputMap) { 6 | var inputMapConsumer = new sourceMap.SourceMapConsumer(inputMap); 7 | var outputMapConsumer = new sourceMap.SourceMapConsumer(map); 8 | 9 | var mergedGenerator = new sourceMap.SourceMapGenerator({ 10 | file: inputMapConsumer.file, 11 | sourceRoot: inputMapConsumer.sourceRoot 12 | }); 13 | 14 | var source = outputMapConsumer.sources[0]; 15 | 16 | inputMapConsumer.eachMapping(function (mapping) { 17 | var generatedPosition = outputMapConsumer.generatedPositionFor({ 18 | line: mapping.generatedLine, 19 | column: mapping.generatedColumn, 20 | source: source 21 | }); 22 | if (generatedPosition.column != null) { 23 | mergedGenerator.addMapping({ 24 | source: mapping.source, 25 | 26 | original: mapping.source == null ? null : { 27 | line: mapping.originalLine, 28 | column: mapping.originalColumn 29 | }, 30 | 31 | generated: generatedPosition 32 | }); 33 | } 34 | }); 35 | 36 | var mergedMap = mergedGenerator.toJSON(); 37 | inputMap.mappings = mergedMap.mappings; 38 | return inputMap 39 | }; 40 | 41 | module.exports = function(source, inputSourceMap) { 42 | var callback = this.async(); 43 | 44 | if (this.cacheable) { 45 | this.cacheable(); 46 | } 47 | 48 | var opts = loaderUtils.getOptions(this) || {}; 49 | // just an indicator to generate source maps, the output result.map will be modified anyway 50 | // tell UglifyJS2 not to emit a name by just setting outSourceMap to true 51 | opts.sourceMap = true; 52 | 53 | var result = UglifyJS.minify(source, opts); 54 | var sourceMap = JSON.parse(result.map); 55 | 56 | if (inputSourceMap) { 57 | callback(null, result.code, mergeSourceMap(sourceMap, inputSourceMap)); 58 | } else { 59 | var sourceFilename = loaderUtils.getRemainingRequest(this); 60 | var current = loaderUtils.getCurrentRequest(this); 61 | sourceMap.sources = [sourceFilename]; 62 | sourceMap.file = current; 63 | sourceMap.sourcesContent = [source]; 64 | 65 | callback(null, result.code, sourceMap); 66 | } 67 | }; 68 | --------------------------------------------------------------------------------