Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is webpack creating output js in form of string and using eval function to deploy it?

My webpack.config.js file is as follows:

var path = require('path'); var webpack = require('webpack'); var CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin; var autoprefixer = require('autoprefixer'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); var CopyWebpackPlugin = require('copy-webpack-plugin'); var ENV = process.env.npm_lifecycle_event; var isTest = ENV === 'test' || ENV === 'test-watch'; var isProd = ENV === 'build';  module.exports = function makeWebpackConfig() {   var config = {};   if (isTest) {     config.devtool = 'inline-source-map';   } else if (isProd) {     config.devtool = 'source-map';   } else {     config.devtool = 'eval-source-map';   }   config.debug = !isProd || !isTest;   config.entry = isTest ? {} : {     'vendor': './src/vendor.ts',     'app': './src/bootstrap.ts' // our angular app   };   config.output = isTest ? {} : {     path: root('../edu_analytics_prod_front/dist'),     publicPath: isProd ? '/' : '/',     filename: isProd ? 'js/[name].[hash].js' : 'js/[name].js',     chunkFilename: isProd ? '[id].[hash].chunk.js' : '[id].chunk.js'   };   config.resolve = {     cache: !isTest,     root: root(),     extensions: ['', '.ts', '.js', '.json', '.css', '.scss', '.html'],     alias: {       'app': 'src/client',       'common': 'src/common'     }   };   config.module = {     preLoaders: isTest ? [] : [{test: /\.ts$/, loader: 'tslint'}],     loaders: [       // Support for .ts files.       {         test: /\.ts$/,         loader: 'ts',         query: {           'ignoreDiagnostics': [             2403, // 2403 -> Subsequent variable declarations             2300, // 2300 -> Duplicate identifier             2374, // 2374 -> Duplicate number index signature             2375, // 2375 -> Duplicate string index signature             2502  // 2502 -> Referenced directly or indirectly           ]         },         exclude: [isTest ? /\.(e2e)\.ts$/ : /\.(spec|e2e)\.ts$/, /node_modules\/(?!(ng2-.+))/]       },       {test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/, loader: 'file?name=fonts/[name].[hash].[ext]?'},       {test: /\.json$/, loader: 'json'},       {         test: /\.css$/,         exclude: root('src', 'client'),         loader: isTest ? 'null' : ExtractTextPlugin.extract('style', 'css?sourceMap!postcss')       },       // all css required in src/client files will be merged in js files       {test: /\.css$/, include: root('src', 'client'), loader: 'raw!postcss'},       {         test: /\.scss$/,         exclude: root('src', 'client'),         loader: isTest ? 'null' : ExtractTextPlugin.extract('style', 'css?sourceMap!postcss!sass')       },       {test: /\.scss$/, exclude: root('src', 'style'), loader: 'raw!postcss!sass'},       {test: /\.html$/, loader: 'raw'}     ],     postLoaders: [],     noParse: [/.+angular2\/bundles\/.+/]   };   if (isTest) {     config.module.postLoaders.push({       test: /\.(js|ts)$/,       include: path.resolve('src'),       loader: 'istanbul-instrumenter-loader',       exclude: [/\.spec\.ts$/, /\.e2e\.ts$/, /node_modules/]     })   }   config.plugins = [     new webpack.DefinePlugin({       'process.env': {         ENV: JSON.stringify(ENV)       }     })   ];   if (!isTest) {     config.plugins.push(       new CommonsChunkPlugin({         name: ['vendor', 'polyfills']       }),       new HtmlWebpackPlugin({         template: './src/public/index.html',         inject: 'body',         chunksSortMode: packageSort(['polyfills', 'vendor', 'app'])       }),       new webpack.optimize.UglifyJsPlugin({         compress: { warnings: false }       }),       new ExtractTextPlugin('css/[name].[hash].css', {disable: !isProd})     );   }   if (isProd) {     config.plugins.push(       new webpack.NoErrorsPlugin(),       new webpack.optimize.DedupePlugin(),       new webpack.optimize.UglifyJsPlugin({         compress: { warnings: false }       }),       new CopyWebpackPlugin([{         from: root('src/public')       }])     );   }   config.postcss = [     autoprefixer({       browsers: ['last 2 version']     })   ];   config.sassLoader = {     //includePaths: [path.resolve(__dirname, "node_modules/foundation-sites/scss")]   };   config.tslint = {     emitErrors: false,     failOnHint: false   };   config.devServer = {     contentBase: './src/public',     historyApiFallback: true,     stats: 'minimal' // none (or false), errors-only, minimal, normal (or true) and verbose   };    return config; }();  function root(args) {   args = Array.prototype.slice.call(arguments, 0);   return path.join.apply(path, [__dirname].concat(args)); }  function rootNode(args) {   args = Array.prototype.slice.call(arguments, 0);   return root.apply(path, ['node_modules'].concat(args)); }  function packageSort(packages) {   var len = packages.length - 1;   var first = packages[0];   var last = packages[len];   return function sort(a, b) {     if (a.names[0] === first) {       return -1;     }     if (a.names[0] === last) {       return 1;     }     if (a.names[0] !== first && b.names[0] === last) {       return -1;     } else {       return 1;     }   } } 

When I'm running command like webpack / webpack -p

It is creating three files as follows:

file structure

But all three files has output as string and using eval function to deploy it and one file has very big size(7 MB) as follows. code inside

I want simple JavaScript file without eval used inside it as all other common minification library works and I want to reduce size of vendor file as well.

like image 545
Akhilesh Kumar Avatar asked Aug 26 '16 10:08

Akhilesh Kumar


People also ask

Why do Webpacks use eval?

Using “development” mode webpack will use “eval” for devtool which is designed more for build performance than map quality, you will still have to override this if you want better maps.

Why do we use eval in JavaScript?

The eval() function evaluates JavaScript code represented as a string and returns its completion value. The source is parsed as a script.

What is output in webpack?

The top-level output key contains a set of options instructing webpack on how and where it should output your bundles, assets, and anything else you bundle or load with webpack.

Why we should not use eval in JavaScript?

Malicious code : invoking eval can crash a computer. For example: if you use eval server-side and a mischievous user decides to use an infinite loop as their username. Terribly slow : the JavaScript language is designed to use the full gamut of JavaScript types (numbers, functions, objects, etc)… Not just strings!


1 Answers

Your config uses this configuration as default:

config.devtool = 'eval-source-map'; 

The fine manual states:

eval-source-map - Each module is executed with eval and a SourceMap is added as DataUrl to the eval.

If you don't want that, use another devtool option.

As for decreasing code size, you probably want to either disable the creation of a source map entirely (just don't set the devtool option) or have Webpack write the source map to a separate file (devtool : 'source-map' or devtool : 'cheap-source-map', AFAIK).

Also set the NODE_ENV environment variable to production if you want less code:

# if you're on a Unix-like OS: env NODE_ENV=production webpack -p 
like image 106
robertklep Avatar answered Oct 05 '22 17:10

robertklep