Giter Site home page Giter Site logo

compression-webpack-plugin's Introduction

npm node tests cover discussion size

compression-webpack-plugin

Prepare compressed versions of assets to serve them with Content-Encoding.

Getting Started

To begin, you'll need to install compression-webpack-plugin:

npm install compression-webpack-plugin --save-dev

or

yarn add -D compression-webpack-plugin

or

pnpm add -D compression-webpack-plugin

Then add the plugin to your webpack config. For example:

webpack.config.js

const CompressionPlugin = require("compression-webpack-plugin");

module.exports = {
  plugins: [new CompressionPlugin()],
};

And run webpack via your preferred method.

Options

test

Type:

type test = string | RegExp | Array<string | RegExp>;

Default: undefined

Include all assets that pass test assertion.

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      test: /\.js(\?.*)?$/i,
    }),
  ],
};

include

Type:

type include = string | RegExp | Array<string | RegExp>;

Default: undefined

Include all assets matching any of these conditions.

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      include: /\/includes/,
    }),
  ],
};

exclude

Type:

type exclude = string | RegExp | Array<string | RegExp>;

Default: undefined

Exclude all assets matching any of these conditions.

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      exclude: /\/excludes/,
    }),
  ],
};

algorithm

Type:

type algorithm =
  | string
  | ((
      input: Buffer,
      options: CompressionOptions,
      callback: (
        error: Error | null | undefined,
        result:
          | string
          | ArrayBuffer
          | SharedArrayBuffer
          | Uint8Array
          | readonly number[]
          | {
              valueOf(): ArrayBuffer | SharedArrayBuffer;
            }
          | {
              valueOf(): string | Uint8Array | readonly number[];
            }
          | {
              valueOf(): string;
            }
          | {
              [Symbol.toPrimitive](hint: "string"): string;
            },
      ) => void,
    ) => any);

Default: gzip

The compression algorithm/function.

Note

If you use custom function for the algorithm option, the default value of the compressionOptions option is {}.

string

The algorithm is taken from zlib.

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      algorithm: "gzip",
    }),
  ],
};

function

Allow to specify a custom compression function.

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      algorithm(input, compressionOptions, callback) {
        return compressionFunction(input, compressionOptions, callback);
      },
    }),
  ],
};

compressionOptions

Type:

type compressionOptions = {
  flush?: number;
  finishFlush?: number;
  chunkSize?: number;
  windowBits?: number;
  level?: number;
  memLevel?: number;
  strategy?: number;
  dictionary?: Buffer | TypedArray | DataView | ArrayBuffer;
  info?: boolean;
  maxOutputLength?: number;
};

Default: { level: 9 }

Compression options for algorithm.

You can find all options here zlib.

Note

If you use custom function for the algorithm option, the default value is {}.

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      compressionOptions: { level: 1 },
    }),
  ],
};

threshold

Type:

type threshold = number;

Default: 0

Only assets bigger than this size are processed. In bytes.

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      threshold: 8192,
    }),
  ],
};

minRatio

Type:

type minRatio = number;

Default: 0.8

Only assets that compress better than this ratio are processed (minRatio = Compressed Size / Original Size). Example: you have image.png file with 1024b size, compressed version of file has 768b size, so minRatio equal 0.75. In other words assets will be processed when the Compressed Size / Original Size value less minRatio value.

You can use 1 value to process assets that are smaller than the original.

Use a value of Infinity to process all assets even if they are larger than the original size or their original size is 0 bytes (useful when you are pre-zipping all assets for AWS).

Use a value of Number.MAX_SAFE_INTEGER to process all assets even if they are larger than the original size, excluding assets with their original size is 0 bytes.

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      // Compress all assets, including files with `0` bytes size
      // minRatio: Infinity

      // Compress all assets, excluding files with `0` bytes size
      // minRatio: Number.MAX_SAFE_INTEGER

      minRatio: 0.8,
    }),
  ],
};

filename

Type:

type filename = string | ((pathdata: PathData) => string);

Default: "[path][base].gz"

The target asset filename.

string

For example we have assets/images/image.png?foo=bar#hash:

[path] is replaced with the directories to the original asset, included trailing / (assets/images/).

[file] is replaced with the path of original asset (assets/images/image.png).

[base] is replaced with the base ([name] + [ext]) of the original asset (image.png).

[name] is replaced with the name of the original asset (image).

[ext] is replaced with the extension of the original asset, included . (.png).

[query] is replaced with the query of the original asset, included ? (?foo=bar).

[fragment] is replaced with the fragment (in the concept of URL it is called hash) of the original asset (#hash).

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      filename: "[path][base].gz",
    }),
  ],
};

function

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      filename(pathData) {
        // The `pathData` argument contains all placeholders - `path`/`name`/`ext`/etc
        // Available properties described above, for the `String` notation
        if (/\.svg$/.test(pathData.filename)) {
          return "assets/svg/[path][base].gz";
        }

        return "assets/js/[path][base].gz";
      },
    }),
  ],
};

deleteOriginalAssets

Type:

type deleteOriginalAssets =
  | boolean
  | "keep-source-map"
  | ((name: string) => boolean);

Default: false

Whether to delete the original assets or not.

webpack.config.js

module.exports = {
  plugins: [
    new CompressionPlugin({
      deleteOriginalAssets: true,
    }),
  ],
};

To exclude sourcemaps from compression:

module.exports = {
  plugins: [
    new CompressionPlugin({
      exclude: /.map$/,
      deleteOriginalAssets: "keep-source-map",
    }),
  ],
};

Using a custom function:

module.exports = {
  plugins: [
    new CompressionPlugin({
      exclude: /.map$/,
      deleteOriginalAssets: (name) => {
        if (/\.js$/.test(name)) {
          return false;
        }

        return true;
      },
    }),
  ],
};

Examples

Using Zopfli

Prepare compressed versions of assets using zopfli library.

Note

@gfx/zopfli require minimum 8 version of node.

To begin, you'll need to install @gfx/zopfli:

$ npm install @gfx/zopfli --save-dev

webpack.config.js

const zopfli = require("@gfx/zopfli");

module.exports = {
  plugins: [
    new CompressionPlugin({
      compressionOptions: {
        numiterations: 15,
      },
      algorithm(input, compressionOptions, callback) {
        return zopfli.gzip(input, compressionOptions, callback);
      },
    }),
  ],
};

Using Brotli

Brotli is a compression algorithm originally developed by Google, and offers compression superior to gzip.

Node 10.16.0 and later has native support for Brotli compression in its zlib module.

We can take advantage of this built-in support for Brotli in Node 10.16.0 and later by just passing in the appropriate algorithm to the CompressionPlugin:

webpack.config.js

const zlib = require("zlib");

module.exports = {
  plugins: [
    new CompressionPlugin({
      filename: "[path][base].br",
      algorithm: "brotliCompress",
      test: /\.(js|css|html|svg)$/,
      compressionOptions: {
        params: {
          [zlib.constants.BROTLI_PARAM_QUALITY]: 11,
        },
      },
      threshold: 10240,
      minRatio: 0.8,
      deleteOriginalAssets: false,
    }),
  ],
};

[!NOTE] Brotli’s BROTLI_PARAM_QUALITY option is functionally equivalent to zlib’s level option. You can find all Brotli’s options in the relevant part of the zlib module documentation.

Multiple compressed versions of assets for different algorithm

webpack.config.js

const zlib = require("zlib");

module.exports = {
  plugins: [
    new CompressionPlugin({
      filename: "[path][base].gz",
      algorithm: "gzip",
      test: /\.js$|\.css$|\.html$/,
      threshold: 10240,
      minRatio: 0.8,
    }),
    new CompressionPlugin({
      filename: "[path][base].br",
      algorithm: "brotliCompress",
      test: /\.(js|css|html|svg)$/,
      compressionOptions: {
        params: {
          [zlib.constants.BROTLI_PARAM_QUALITY]: 11,
        },
      },
      threshold: 10240,
      minRatio: 0.8,
    }),
  ],
};

Contributing

Please take a moment to read our contributing guidelines if you haven't yet done so.

CONTRIBUTING

License

MIT

compression-webpack-plugin's People

Contributors

ai avatar alexander-akait avatar anshumanv avatar cap-bernardito avatar codechaotic avatar commanderroot avatar dependabot[bot] avatar ersachin3112 avatar evilebottnawi avatar gfx avatar graingert avatar harish-sethuraman avatar hecktarzuli avatar icehunter avatar ijpiantanida avatar jamesgeorge007 avatar joshwiens avatar michael-ciniawsky avatar nickbouldien avatar robertbachmann avatar ronen-e avatar rufman avatar shama avatar shfshanyue avatar sibiraj-s avatar skipjack avatar snitin315 avatar sokra avatar stavrus avatar stijnvn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

compression-webpack-plugin's Issues

How to use/render bundle.js.gz in html file

webpack.config.js


var CompressionPlugin = require('compression-webpack-plugin');
/*...................................*/
  output: {
    path: PROD ? path.resolve(ROOT_PATH, 'dist') :
      path.resolve(ROOT_PATH, 'app/build'),
    publicPath: '/',
    filename: 'bundle.js',
  },
/*....................................*/
    new CompressionPlugin({
      asset: "[path].gz[query]",
      algorithm: "gzip",
      test: /\.js$|\.css$|\.html$/,
      threshold: 10240,
      minRatio: 0.8
    })
/*....................................*/

server.js

const serve = require('koa-static');
const send = require('koa-send');
const koa = require('koa');
const app = koa();
app.use(serve(__dirname + '/app/build'));
app.use(function* index() {
  yield send(this, './app/build/index.html');
});
app.listen(9090);
console.log("listening on 9090");

output files:

vendor.bundle.js 1.38 MB 0 [emitted] vendor
bundle.js 943 kB 1 [emitted] app
vendor.bundle.js.map 9.83 MB 0 [emitted] vendor
bundle.js.map 4.13 MB 1 [emitted] app
bundle.js.gz 165 kB [emitted]
vendor.bundle.js.gz 361 kB [emitted]
index.html 323 bytes [emitted]

index.html ( is the following code is correct to render the above build files)


<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>myapp</title>
  </head>
  <body>
    <div id="app"></div>
     <script src="/vendor.bundle.js.gz"></script>
    <script src="/bundle.js.gz"></script>
  </body>
</html>

Unable to render my app page by using the above code, is the above index.html code is correct to render the build files

algorithm function now takes options param which is always an empty object

0.3.1 (specifically #18) changed the algorithm option's signature from function(buf, callback) to function(buf, options, callback), but options is pointless as it's always an empty object.

this.compressionOptions is only populated if this.algorithm is a string

It seems to me that there are two options:

1. Remove the option arg added in 0.3.1

Pros:

  • Simpler code
  • Options is not really needed as the algorithm function can obtain options from its closure

Cons:

  • Would re-break configs for people who've now adapted to the the API change introduced in 0.3.1

2. Populate the option object with values so that it's not always empty

Pros:

  • Option arg would serve a purpose
  • Can configure custom algorithm functions without using an anon func & closure each time

Cons:

  • Not really sure that it's helpful/required

My inclination is to go with option 1 to keep things simple, but perhaps it's best to go with 2 to avoid changing the algorithm func signature a second time. I'll create a PR for each option in a sec.

Error running install script for optional dependency

When I install this plugin I keep getting this error in console. It happens when I wanna install or remove any npm package.

Error running install script for optional dependency: "C:\\Users\\igvuk\\Desktop\\Projects-git\\Ultimate React Boilerplate\\node_modules\\node-zopfli: Command failed.\nExit code: 1\nCommand: C:\\WINDOWS\\system32\\cmd.exe\nArguments: /d /s /c node-pre-gyp install --fallback-to-build\nDirectory: C:\\Users\\igvuk\\Desktop\\Projects-git\\Ultimate React Boilerplate\\node_modules\\node-zopfli
\nOutput:\nnode-pre-gyp info it worked if it ends with ok\nnode-pre-gyp info using [email protected]\nnode-pre-gyp info using [email protected] | win32 | x64\nnode-pre-gyp info check checked for \"C:\\Users\\igvuk\\Desktop\\Projects-git\\Ultimate React Boilerplate\\node_modules\\node-zopfli\\lib\\binding\\node-v57-win32-x64\\zopfli.node\" (not found)\nnode-pre-gyp http GET https://node-zopfli.s3.amaz
onaws.com/Release/zopfli-v2.0.2-node-v57-win32-x64.tar.gz\nnode-pre-gyp http 403 https://node-zopfli.s3.amazonaws.com/Release/zopfli-v2.0.2-node-v57-win32-x64.tar.gz\nnode-pre-gyp ERR! Tried to download(403): https://node-zopfli.s3.amazonaws.com/Release/zopfli-v2.0.2-node-v57-win32-x64.tar.gz \nnode-pre-gyp ERR! Pre-built binaries not found for [email protected] and [email protected] (node-v57 ABI) (fa
lling back to source compile with node-gyp) \nnode-pre-gyp http 403 status code downloading tarball https://node-zopfli.s3.amazonaws.com/Release/zopfli-v2.0.2-node-v57-win32-x64.tar.gz \ngyp info it worked if it ends with ok\ngyp info using [email protected]\ngyp info using [email protected] | win32 | x64\ngyp info ok \ngyp info it worked if it ends with ok\ngyp info using [email protected]\ngyp info using n
[email protected] | win32 | x64\ngyp ERR! configure error \ngyp ERR! stack Error: Can't find Python executable \"python\", you can set the PYTHON env variable.\ngyp ERR! stack     at PythonFinder.failNoPython (C:\\Users\\igvuk\\Desktop\\Projects-git\\Ultimate React Boilerplate\\node_modules\\node-gyp\\lib\\configure.js:483:19)\ngyp ERR! stack     at PythonFinder.<anonymous> (C:\\Users\\igvuk\\Desktop\\P
rojects-git\\Ultimate React Boilerplate\\node_modules\\node-gyp\\lib\\configure.js:508:16)\ngyp ERR! stack     at C:\\Users\\igvuk\\Desktop\\Projects-git\\Ultimate React Boilerplate\\node_modules\\graceful-fs\\polyfills.js:284:29\ngyp ERR! stack     at FSReqWrap.oncomplete (fs.js:152:21)\ngyp ERR! System Windows_NT 10.0.14393\ngyp ERR! command \"C:\\\\Program Files\\\\nodejs\\\\node.exe\" \"C:\\
\\Users\\\\igvuk\\\\Desktop\\\\Projects-git\\\\Ultimate React Boilerplate\\\\node_modules\\\\node-gyp\\\\bin\\\\node-gyp.js\" \"configure\" \"--fallback-to-build\" \"--module=C:\\\\Users\\\\igvuk\\\\Desktop\\\\Projects-git\\\\Ultimate React Boilerplate\\\\node_modules\\\\node-zopfli\\\\lib\\\\binding\\\\node-v57-win32-x64\\\\zopfli.node\" \"--module_name=zopfli\" \"--module_path=C:\\\\Users\\\\i
gvuk\\\\Desktop\\\\Projects-git\\\\Ultimate React Boilerplate\\\\node_modules\\\\node-zopfli\\\\lib\\\\binding\\\\node-v57-win32-x64\"\ngyp ERR! cwd C:\\Users\\igvuk\\Desktop\\Projects-git\\Ultimate React Boilerplate\\node_modules\\node-zopfli\ngyp ERR! node -v v8.1.3\ngyp ERR! node-gyp -v v3.6.2\ngyp ERR! not ok \nnode-pre-gyp ERR! build error \nnode-pre-gyp ERR! stack Error: Failed to execute
'C:\\Program Files\\nodejs\\node.exe C:\\Users\\igvuk\\Desktop\\Projects-git\\Ultimate React Boilerplate\\node_modules\\node-gyp\\bin\\node-gyp.js configure --fallback-to-build --module=C:\\Users\\igvuk\\Desktop\\Projects-git\\Ultimate React Boilerplate\\node_modules\\node-zopfli\\lib\\binding\\node-v57-win32-x64\\zopfli.node --module_name=zopfli --module_path=C:\\Users\\igvuk\\Desktop\\Projects
-git\\Ultimate React Boilerplate\\node_modules\\node-zopfli\\lib\\binding\\node-v57-win32-x64' (1)\nnode-pre-gyp ERR! stack     at ChildProcess.<anonymous> (C:\\Users\\igvuk\\Desktop\\Projects-git\\Ultimate React Boilerplate\\node_modules\\node-pre-gyp\\lib\\util\\compile.js:83:29)\nnode-pre-gyp ERR! stack     at emitTwo (events.js:125:13)\nnode-pre-gyp ERR! stack     at ChildProcess.emit (event
s.js:213:7)\nnode-pre-gyp ERR! stack     at maybeClose (internal/child_process.js:897:16)\nnode-pre-gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:208:5)\nnode-pre-gyp ERR! System Windows_NT 10.0.14393\nnode-pre-gyp ERR! command \"C:\\\\Program Files\\\\nodejs\\\\node.exe\" \"C:\\\\Users\\\\igvuk\\\\Desktop\\\\Projects-git\\\\Ultimate React Boilerplate\\\\n

Doesn't hook up my files

Hello! I'm trying to make build and deployment system for my project. I want to be able to serve gzipped vendor and custom JS files, and merged and gzipped single CSS file (cause vendor chunk also has some css in it). If I don't merge css with merge-files-webpack-plugin, everything goes well and I see 2 css files in the output, BUT when merging, I see my combined style.css intact(with deleteOriginalAssets: true) and no gzipped css. Seems like something's wrong with the order, or RegExp, or something...Please help! Webpack 2. Here's the code:

var path = require('path');
var webpack = require ('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var MergeFilesPlugin = require('merge-files-webpack-plugin');
var OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
var cssProcessor = require('cssnano');
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
var CompressionPlugin = require('compression-webpack-plugin');


const VENDOR_LIBS = [ 'axios', 'crypto-js', 'jstimezonedetect', 'lodash', 'normalizr', 'react-motion', 'react', 'react-dom', 'react-router', 'redux-form', 'react-redux', 'react-router-redux', 'react-swipeable-views', 'react-tap-event-plugin', 'recompose', 'redux', 'redux-form-material-ui', 'redux-mediaquery', 'redux-thunk', 'reselect', 'reset-css', 'socket.io-client', 'material-ui/FlatButton', 'material-ui/TextField', 'material-ui/Table', 'material-ui/SelectField', 'material-ui/MenuItem', 'material-ui/Stepper', 'material-ui/Checkbox', 'material-ui/styles/colors',
'material-ui/Tabs', 'material-ui/FloatingActionButton', 'material-ui/DropDownMenu', 'material-ui/utils/colorManipulator', 'material-ui/Dialog', 'material-ui/CircularProgress', 'material-ui/Snackbar', 'material-ui/styles/MuiThemeProvider', 'material-ui/styles/getMuiTheme', 'material-ui/styles/spacing' ];

const config = {
  entry: {
  app: [ 'babel-polyfill', './app/index.js' ],
  vendor: VENDOR_LIBS
  },

  output: {
    path: path.resolve(__dirname, 'build'),
    publicPath: 'build/',
    filename: '[name].js',
  },

  plugins: [
    new webpack.optimize.OccurrenceOrderPlugin(),

    new webpack.DefinePlugin({
      'process.env': {
        'NODE_ENV': JSON.stringify('production')
      }
    }),

    new ExtractTextPlugin('[name].css'),

    new MergeFilesPlugin({
           filename: 'style.css',
           test: /\.css$/,
           deleteSourceFiles: true
       }),

       new OptimizeCssAssetsPlugin({
         assetNameRegExp: /\.css$/g,
         cssProcessor: cssProcessor,
         cssProcessorOptions: { discardComments: {removeAll: true} },
         safe: true,
         canPrint: true
       }),

       new CompressionPlugin({
         asset: 'gzip/[file][query]',
         algorithm: 'gzip',
         test: /style.css/g,
         threshold: 0,
         minRatio: 0.8,
         deleteOriginalAssets: true
       }),


    new webpack.optimize.CommonsChunkPlugin({
        name: 'vendor',
        minChunks: Infinity,
        filename: '[name].js',
      }),



    new webpack.optimize.UglifyJsPlugin({
      sourceMap: false,
      compressor: {
        warnings: false
      }
    }),

  /*  new BundleAnalyzerPlugin({
            analyzerMode: 'static'
        }), */



    new CompressionPlugin({
      asset: 'gzip/[file][query]',
      algorithm: 'gzip',
      test: /\.js$/g,
      threshold: 0,
      minRatio: 0.8
    //  ,deleteOriginalAssets: true
  })



  ],
  module: {
    rules: [

      {
        test: /\.json$/,
        use: 'json-loader'
      },
      {
        test: /\.(png|jpe?g|gif|svg)$/,
        use: [
          {
            loader: 'file-loader?name=[path][name].[ext]',
            options: { limit: 40000, outputPath: 'images/' }
          },
          'image-webpack-loader'
            ]
      },
      {
        test: /\.css$/,
         use: ExtractTextPlugin.extract({
           fallback: 'style-loader',
           use: [
            'css-loader?modules&localIdentName=[path][name]_[local]--[hash:base64:8]',
             {
               loader: 'postcss-loader',
               options: {
                 importLoaders: 1
               }
             }

           ]
         })

      },
      {
        use: [{
          loader: 'babel-loader',
          options: { presets: ['react', 'es2015', 'stage-1'] },
        }],
        test: /\.js$/,
        exclude: /node_modules/
      }
    ]
  },
  resolve: {
    extensions: ['*', '.js', '.jsx', '.json']
  },
  devtool: false,
  devServer: {

    historyApiFallback: true,
    contentBase: './app'
  }
};

module.exports = config;

Not minifying?

Hi Tobias!

I'm probably doing something wrong but I can't get the CompressionPlugin to generate the final gzipped .gz file during production build.

Here's my webpack.config file:

var webpack = require('webpack');
var baseConfig = require('./webpack/base-config');
var configurationCreator = require('webpack-configuration');
var CompressionPlugin = require('compression-webpack-plugin');
var path = require('path');

module.exports = configurationCreator(baseConfig, {
commonsChunk: false,
longTermCaching: false,
extractCSS: true,
path: 'server/cloud/assets/',
publicPath: "server/cloud/assets/",
versionMap: path.join(__dirname, 'server/assets.json'),
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new webpack.optimize.DedupePlugin(),
new CompressionPlugin({
asset: "{file}.gz",
algorithm: "gzip",
regExp: /.js$/,
threshold: 0,
minRatio: 0.8
})
]
});

This does, however, produce the minified .js in 'server/cloud/assets/'. Any help would be greatly appreciated!

Error "Algorithm not found in zlib"

EDIT: working now, replaced: algorithm: 'gzipMaxCompression', with just gzip. Not sure where I picked up that config. Thanks.

Trying to use this plugin on Windows and getting the error: "Algorithm not found in zlib"

node_modules\compression-webpack-plugin\index.js:36
if(!this.algorithm) throw new Error("Algorithm not found in zlib");

I'm on Windows10 pro and have followed the setup as per
https://www.serverpals.com/blog/building-using-node-gyp-with-visual-studio-express-2015-on-windows-10-pro-x64
... ie install VS, Python, added environment variables
This got rid of the previous errors with node-gyp, but now getting this new error.

Help compress JSON files

Hi guys!
I like your plugin, I often use it!
But there is a problem that json files are not compressed.
Maybe I'm using the plugin incorrectly for such tasks.

Webpack copy all static files (with subdirectory /dl) from src/static to ../back-end/data (prodaction folder).
Plugin compress main.js and style.css - OK, but JSON no compress (../back-end/data/dl).

Help me please.
My webpack.config.json:

const path = require('path');
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CompressionPlugin = require("compression-webpack-plugin");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const PostCSSAssetsPlugin = require('postcss-assets-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = function (env) {
    const outputPath = path.join(__dirname, '../back-end/data');
    const exports = {
        cache: true,
        entry: {main: './src/index'},
        output: {
            path: outputPath,
            filename: '[name].js',
            publicPath: '/'
        },
        plugins: [
            new CleanWebpackPlugin(path.join(outputPath, '*'), {root: path.join(__dirname, '..'), verbose: false}),
            new ExtractTextPlugin('style.css'),
            new PostCSSAssetsPlugin({
                test: /\.css$/,
                log: false,
                plugins: [
                    require('precss'),
                    require('autoprefixer')
                ],
            })
        ],
        module: {
            rules: [
                {
                    test: /\.js$/,
                    loader: 'babel-loader',
                    include: [path.resolve(__dirname, "src")],
                    exclude: /(node_modules|bower_components)/,
                    options: {cacheDirectory: path.resolve(__dirname, 'babel_cache/')}
                },
                {
                    test: /\.s?css$/,
                    use: ExtractTextPlugin.extract({
                        fallback: 'style-loader',
                        use: ['css-loader', 'sass-loader']
                    })
                },
                {
                    test: /\.json$/,
                    loader: 'json-loader'
                }
            ]
        }
    };
    const copyTargets = [ {from: 'src/static/', to: './'} ];
    exports.plugins.push(new CopyWebpackPlugin(copyTargets));
    if (env && env.compress) {
        exports.plugins.push(new CompressionPlugin({
            asset: "[path].gz[query]",
            algorithm: "gzip",
            test: /\.(js|css|json)$/,
            threshold: 8192,
            minRatio: 0.8,
            deleteOriginalAssets: true
        }));
    }
    return exports;
};

TypeError: object is not a function

When I added new CompressionPlugin() to plugin array. I am getting a error.

zlib.js:167
      callback(null, buf);
      ^
  TypeError: object is not a function
      at Gzip.onEnd (zlib.js:167:5)
      at Gzip.emit (events.js:117:20)
      at _stream_readable.js:944:16
      at process._tickCallback (node.js:448:13)

node: v0.10.40
npm: 1.4.28

.gz file names not updated in index.html

Hello, I am using this plugin to gzip my bundle and chunk js so that my application should load faster. I followed integration steps and build generates .gz files too but those .gz file names are not updated in index.html Have anyone face this issue?

Also it adds scripts two times in index.html

  1. In Head: as link and type preload
  2. In Body: as script and type test/javascript
    can you explain me why it is used two times?

my index.html file still looks like:

<!doctype html>
<html lang=en>

<head>
<title>Gzip compression</title>
<base href="/">
<link rel="stylesheet" href="assets/css/style.css">  
<link rel="preload" href="polyfills.bundle.js" as="script"/><link rel="preload" href="main.bundle.js" as="script"/>
</head>

<body>
<app>Loading...</app>
<script type="text/javascript" src="polyfills.bundle.js"></script><script type="text/javascript" src="main.bundle.js" async></script
</body>

</html>

Only 1 file is compressed

Hi!
At me a problem, only 1 file is compressed, remaining remain as is.

exports.plugins.push(new CopyWebpackPlugin(copyTargets));
  if (env && env.compress) {
    exports.plugins.push(new CompressionPlugin({
      asset: "[path].gz[query]",
      algorithm: "gzip",
      test: /\.(js|css|json)$/,
      threshold: 8192,
      minRatio: 0.8,
      deleteOriginalAssets: true
    }));
  }

Webpack copy all json files to a folder and have to compress them all individually, but only 1 file compresses.
Use 1.1.2 version

install error

I have errors installing this project. This is affecting any project that has this project as a dependency. I've cross referenced this error both downstream and upstream. Until this node-zopfli error is resolved, I recommend not using node-zopfli as a dependency.

I have the latest stable node (5.10.1) and npm (3.8.3)

I get similar errors on both Ubuntu 14.04 and 15.10.
Just now, I cloned this project (compression-webpack-plugin) and ran npm i:

> [email protected] install /home/bkinsey/opt/webpack/compression-webpack-plugin/node_modules/node-zopfli
> node-pre-gyp install --fallback-to-build

gyp WARN download NVM_NODEJS_ORG_MIRROR is deprecated and will be removed in node-gyp v4, please use NODEJS_ORG_MIRROR
gyp WARN download NVM_NODEJS_ORG_MIRROR is deprecated and will be removed in node-gyp v4, please use NODEJS_ORG_MIRROR
gyp WARN download NVM_NODEJS_ORG_MIRROR is deprecated and will be removed in node-gyp v4, please use NODEJS_ORG_MIRROR
make: Entering directory '/home/bkinsey/opt/webpack/compression-webpack-plugin/node_modules/node-zopfli/build'
  CXX(target) Release/obj.target/zopfli/src/zopfli-binding.o
../src/zopfli-binding.cc: In static member function ‘static Nan::NAN_METHOD_RETURN_TYPE nodezopfli::CompressBinding::Sync(Nan::NAN_METHOD_ARGS_TYPE)’:
../src/zopfli-binding.cc:173:20: warning: ‘format’ may be used uninitialized in this function [-Wmaybe-uninitialized]
     &out, &outsize);
                    ^
../src/zopfli-binding.cc: In static member function ‘static Nan::NAN_METHOD_RETURN_TYPE nodezopfli::CompressBinding::Async(Nan::NAN_METHOD_ARGS_TYPE)’:
../src/zopfli-binding.cc:105:78: warning: ‘format’ may be used uninitialized in this function [-Wmaybe-uninitialized]
  : Nan::AsyncWorker(callback), format(format), zopfli_options(zopfli_options) {
                                                                             ^
../src/zopfli-binding.cc:150:16: note: ‘format’ was declared here
   ZopfliFormat format;
                ^
  CXX(target) Release/obj.target/zopfli/src/png/zopflipng.o
  CC(target) Release/obj.target/zopfli/zopfli/src/zopfli/blocksplitter.o
  CC(target) Release/obj.target/zopfli/zopfli/src/zopfli/cache.o
  CC(target) Release/obj.target/zopfli/zopfli/src/zopfli/deflate.o
  CC(target) Release/obj.target/zopfli/zopfli/src/zopfli/gzip_container.o
  CC(target) Release/obj.target/zopfli/zopfli/src/zopfli/hash.o
  CC(target) Release/obj.target/zopfli/zopfli/src/zopfli/katajainen.o
  CC(target) Release/obj.target/zopfli/zopfli/src/zopfli/lz77.o
  CC(target) Release/obj.target/zopfli/zopfli/src/zopfli/squeeze.o
  CC(target) Release/obj.target/zopfli/zopfli/src/zopfli/tree.o
  CC(target) Release/obj.target/zopfli/zopfli/src/zopfli/util.o
  CC(target) Release/obj.target/zopfli/zopfli/src/zopfli/zlib_container.o
  CC(target) Release/obj.target/zopfli/zopfli/src/zopfli/zopfli_lib.o
  CXX(target) Release/obj.target/zopfli/zopfli/src/zopflipng/zopflipng_lib.o
  CXX(target) Release/obj.target/zopfli/zopfli/src/zopflipng/lodepng/lodepng.o
  CXX(target) Release/obj.target/zopfli/zopfli/src/zopflipng/lodepng/lodepng_util.o
  SOLINK_MODULE(target) Release/obj.target/zopfli.node
  COPY Release/zopfli.node
  COPY /home/bkinsey/opt/webpack/compression-webpack-plugin/node_modules/node-zopfli/lib/binding/node-v47-linux-x64/zopfli.node
  TOUCH Release/obj.target/action_after_build.stamp
make: Leaving directory '/home/bkinsey/opt/webpack/compression-webpack-plugin/node_modules/node-zopfli/build'
[email protected] /home/bkinsey/opt/webpack/compression-webpack-plugin

Compression Level option (or hardcode to 9)

Since ideally this should be part of a build chain that compresses once and then delivers many times (as opposed to live compression) it makes sense to use the highest possible compression level.

Can you please either add an option to specify, or else change the default to use level 9 instead of the zlib default of 6.

Compression doesnt run on code split chunks

If you use require.ensure for code splitting, and the compression plugin at the same time it seems that the compression skips over the chunks and only compresses the main chunk.

My config:

config.output = {
    path: './dist',
    filename: 'assets/js/[name].[hash].min.js',
    chunkFilename: 'assets/js/[name].[chunkhash].min.js',
};

and

    new CompressionPlugin({
        asset: '{file}.gz',
        algorithm: 'gzip',
        regExp: /\.js$|\.html$/,
        threshold: 10240,
        minRatio: 0.8
    })

[Request] Release version 0.3.2 to npmjs.org

Hey guys,

can you publish version 0.3.2 of compression-webpack-plugin to npmjs.org, please?
I have an issue installing angular-cli on windows machines because references compression-webpack-plugin as Git-Repository. This leads into problems with Cygwin Git.

For further information please refer to angular/angular-cli#2394.

Update documentation about zopfli

CompressionPlugin documentation says you can specify algorithm: 'zopfli', I believe this is not true anymore because of this commit that removed zopfli: 328048a#diff-1fdf421c05c1140f6d71444ea2b27638L17 (see also #65)
Same for webpack documentation: https://webpack.js.org/plugins/compression-webpack-plugin/

If you try to specify algorithm: 'zopfli' it crashes with Error: Algorithm not found in zlib

If CompressionPlugin supports only gzip, then it should be renamed to gzip-webpack-plugin/GzipPlugin.

See also #59

require.ensure doesn't know about .gz

When i use require.ensure, webpack load uncopressed chunk, it will be great if webpack may load gziped chunk for gziped builds, and ungzip for ungzip builds.

[Bug] Dynamic (computed) `import()` chunks aren't compressed

Hi I have some translation js files which imported dynamically like this in the code:

selection_243

And here is the output of my webpack build with compression-webpack-plugin:

selection_244

As you can see in the screen shot, only the first with index "0" is compressed but not the second one.

Any idea for this issue? Thanks a lot in advance for your help.

deleteOriginalAssets not working?

I stll have my original vendor.js bundle alongside vendor.js.gz. Curious if this works with multiple entry points.

new CompressionPlugin({
        test: /\.(js|css|html)$/,
        threshold: 10240,
        deleteOriginalAssets: true,
}),

why i have double output file .gzip and original file !!!

Angular-CLI 1.0.0 RC0
Webpack 2.2.1

i use webpack CompressionPlugin and when i run npm build i found double file with the same name in dist folder, it's correct ???
my code for output in webpack.conf.js :
"output": {
"path": path.join(process.cwd(), "dist"),
"filename": "[name].bundle.js",
"chunkFilename": "[id].chunk.js"
},

2017-03-02

Can't use query strings in asset path

A configuration which includes any query portion to the filename, as might be used for cache busting, leads to the plugin silently failing during compile. For example the following silently fails:

// webpack.config.js
output: {
  path: ROOT,
  filename: '[name].js?[chunkhash]',
}

This should be fixed as it presents an issue for a fairly frequent use case. While there are alternative strategies for cache busting which are compatible with the plugin as it stands, such as including a hash in the filename itself, a plugin like this should be flexible.

I propose the following:

  • Keep the {file} replacement as is for backwards compatibility
  • Add {path} and {query} replacements to allow for flexible handling of filenames with queries

Remove source when renaming orignal file.

Would you be open to this idea if I submit a PR that allow you to delete the source of a file once it's gzipped if the result file name is different than the original with an augument like removeOriginal: true?

We have a case where we only want to keep only the gizped version in gzip folder. asset: "gzip/{file}". We currently do that using a custom plugin exectued right after the compression, but it may be an option that some other people might be interested into having.

Error: Cannot find module 'webpack/lib/RawSource'

module.js:341
    throw err;
    ^

Error: Cannot find module 'webpack/lib/RawSource'
    at Function.Module._resolveFilename (module.js:339:15)
    at Function.Module._load (module.js:290:25)
    at Module.require (module.js:367:17)
    at require (internal/module.js:16:19)
    at Object.<anonymous> (/var/www/showtime-app/node_modules/compression-webpack-plugin/index.js:7:17)
    at Module._compile (module.js:413:34)
    at Object.Module._extensions..js (module.js:422:10)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Module.require (module.js:367:17)

npm ERR! Linux 3.14.32-xxxx-grs-ipv6-64
npm ERR! argv "/home/web/.nvm/versions/node/v5.6.0/bin/node" "/home/web/.nvm/versions/node/v5.6.0/bin/npm" "run" "build"
npm ERR! node v5.6.0
npm ERR! npm  v3.6.0
npm ERR! code ELIFECYCLE
npm ERR! showtimes@ build: `NODE_ENV=production webpack --config ./webpack.config.production.js --progress`
npm ERR! Exit status 1

This seems to be caused by compression-webpack-plugin.

Assets generated by extract-text-webpack-plugin are not compressed

The assets that are created by extract-text-webpack-plugin are not compressed in my web pack builds.

For instance .css files are not compressed. The funny thing is that the .css.map files are compressed.

Has anyone noticed this?
I will post a configuration example tomorrow!

Zopfli support

Zopfli allows to compress files better, that common gzip

TypeError: Property 'source' of object #<Source> is not a function

Webpack 1.7.3 — ok.

Webpack 1.8.0:

/node_modules/webpack/lib/Compiler.js:253
                var content = source.source();
                                     ^
TypeError: Property 'source' of object #<Source> is not a function
    at Tapable.writeOut (/node_modules/webpack/lib/Compiler.js:253:26)
    at Tapable.<anonymous> (/node_modules/webpack/lib/Compiler.js:244:20)
    at /node_modules/webpack/node_modules/async/lib/async.js:125:13
    at Array.forEach (native)
    at _each (/node_modules/webpack/node_modules/async/lib/async.js:46:24)
    at Object.async.each (/node_modules/webpack/node_modules/async/lib/async.js:124:9)
    at Tapable.emitFiles (/node_modules/webpack/lib/Compiler.js:233:20)
    at /node_modules/webpack/node_modules/mkdirp/index.js:29:20
    at Object.oncomplete (fs.js:107:15)

Here is my plugin config:

new gzip({
  asset: '{file}.gz',
  algorithm: 'gzip',
  regExp: /\.js$|\.css$/
}),

Brotli support

Goal of this plugin is to Prepare compressed versions of assets to serve them with Content-Encoding. Currently it supports gzip but it can be expanded to support brotli compression (and maybe combine zopfli - which is there elsewhere in this git org).
Brotli is supported by all modern browsers now. This plugin could provide defaul option to use brotli with fallback to gzip.

Decompression problem

If we compress the static content before the browser asks, some browsers doesnt know how to decompression then their may be a problem. I haven't used this just though of this problem.

Split out node-zopfli

  • Support from node-zopfli will be dropped from compression-webpack-plugin in the next Major release.

zopfli-webpack-plugin will be published with an identical API less the optional dependency.

Relates to #54

webpack-defaults upgrade

Addition of webpack-defaults & associated refactoring as a part of the next Major release

Issue exists for status tracking across the organization.

Please do not close

Chunk name

Hello,

Is there a way to attach a chunk name to this output? Other plugins I use work on the chunks that were output and this plugin doesn't attach any chunk name.

This may not be possible (e.g. this plugin is taking the chunks and compressing them and outputting them), but it would be nice if that were the case that it would delete the old files (this function is already there) and the new files would have the same chunk name as the uncompressed version

Unexpected character added to &nbsp

When compressor is active I get the following:

screen shot 2016-02-28 at 01 12 12

The  should not be there. It is not there when compressor is not active.

my config is as follows:

    new CompressionPlugin({
      asset: '{file}.gz',
      test: /\.js$|\.jpg$/,
      threshold: 10240,
      minRatio: 0.8
    })

how to use the compressed gz file

I run the vue-cli,and build my project.the vendor builded is too large.so i gzip it and turn to several gz files.but i don't know how to use it.its size seem to suitable.

TypeError: Invalid non-string/buffer chunk in v0.3 (worked in v0.2).

In the webpack config under plugins.

new CompressionPlugin({    
   test: /\.js$/
})

The regExp was renamed as per the breaking change. But nothing else has changed. The build will succeed in v0.2 but gets the error in v0.3

Stacktrace:

TypeError: Invalid non-string/buffer chunk
    at validChunk (_stream_writable.js:178:14)
    at Gzip.Writable.write (_stream_writable.js:205:12)
    at Gzip.Writable.end (_stream_writable.js:433:10)
    at zlibBuffer (zlib.js:197:10)
    at Object.exports.gzip (zlib.js:123:10)
    at CompressionPlugin.<anonymous> (<Project>/node_modules/compression-webpack-plugin/index.js:68:10)
    at <Project>/node_modules/async/lib/async.js:111:13
    at Array.forEach (native)
    at _each (<Project>/node_modules/async/lib/async.js:32:24)
    at Object.async.each (<Project>/node_modules/async/lib/async.js:110:9)
    at CompressionPlugin.<anonymous> (<Project>/node_modules/compression-webpack-plugin/index.js:55:10)
    at Compilation.applyPluginsAsync (<Project>/node_modules/tapable/lib/Tapable.js:71:13)
    at Compilation.<anonymous> (<Project>/node_modules/webpack/lib/Compilation.js:572:10)
    at Compilation.next (<Project>/node_modules/tapable/lib/Tapable.js:67:11)
    at Compilation.<anonymous> (<Project>/node_modules/webpack/lib/optimize/UglifyJsPlugin.js:137:4)
    at Compilation.applyPluginsAsync (<Project>/node_modules/tapable/lib/Tapable.js:71:13)
    at Compilation.<anonymous> (<Project>/node_modules/webpack/lib/Compilation.js:567:9)
    at Compilation.next (<Project>/node_modules/tapable/lib/Tapable.js:67:11)
    at ExtractTextPlugin.<anonymous> (<Project>/node_modules/extract-text-webpack-plugin/index.js:309:4)
    at Compilation.applyPluginsAsync (<Project>/node_modules/tapable/lib/Tapable.js:71:13)
    at Compilation.<anonymous> (<Project>/node_modules/webpack/lib/Compilation.js:563:8)
    at Compilation.next (<Project>/node_modules/tapable/lib/Tapable.js:67:11)
    at ExtractTextPlugin.<anonymous> (<Project>/node_modules/extract-text-webpack-plugin/index.js:285:5)
    at <Project>/node_modules/extract-text-webpack-plugin/node_modules/async/lib/async.js:52:16
    at Object.async.forEachOf.async.eachOf (<Project>/node_modules/extract-text-webpack-plugin/node_modules/async/lib/async.js:236:30)
    at Object.async.forEach.async.each (<Project>/node_modules/extract-text-webpack-plugin/node_modules/async/lib/async.js:209:22)
    at ExtractTextPlugin.<anonymous> (<Project>/node_modules/extract-text-webpack-plugin/index.js:237:10)
    at Compilation.applyPluginsAsync (<Project>/node_modules/tapable/lib/Tapable.js:71:13)
    at Compilation.seal (<Project>/node_modules/webpack/lib/Compilation.js:525:7)
    at Compiler.<anonymous> (<Project>/node_modules/webpack/lib/Compiler.js:397:15)

node-zopfli not found eventhough it is installed

/usr/src/app/node_modules/compression-webpack-plugin/index.js:20
				throw new Error("node-zopfli not found");
				^

Error: node-zopfli not found
    at new CompressionPlugin (/usr/src/app/node_modules/compression-webpack-plugin/index.js:20:11)
    at getPluginsConfig (/usr/src/app/webpack.config.js:262:5)
    at Object.<anonymous> (/usr/src/app/webpack.config.js:335:12)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)```

So the require in compression-webpack-plugin/index.js fails...

yarn list | grep node-zopfli
warning [email protected]: License should be a valid SPDX license expression
│  ├─ node-zopfli@^2.0.0
├─ [email protected]

can not work with png and html

config as below:

new CompressionWebpackPlugin({
                asset: '[path].gz[query]',
                algorithm: 'gzip',
                test: new RegExp(
                '\\.(' +
                    ['png', 'gif','html'].join('|') +
                ')$'
                ),
                threshold: 1024,
                minRatio: 0
        })

and i am sure the size of file greater than 1024
output list as below:

Using Compression plugin alongside 'html-webpack-plugin'

Is it possible to make the Html Webpack plugin insert a link to the .gz build file instead of the normal .js build file?

Is this even the right place to ask this question??

Thanks for your help, and thanks for your work on a great plugin!

TypeError: Property 'source' of object #<Source> is not a function

I am getting this error with the webpack version 1.9.12

  /Users/newuser/w/citiesense/search/node_modules/webpack/lib/Compiler.js:254
          var content = source.source();
                               ^
  TypeError: Property 'source' of object #<Source> is not a function
      at Tapable.writeOut (/Users/newuser/w/citiesense/search/node_modules/webpack/lib/Compiler.js:254:26)
      at Tapable.<anonymous> (/Users/newuser/w/citiesense/search/node_modules/webpack/lib/Compiler.js:245:20)
      at /Users/newuser/w/citiesense/search/node_modules/webpack/node_modules/async/lib/async.js:122:13
      at _each (/Users/newuser/w/citiesense/search/node_modules/webpack/node_modules/async/lib/async.js:46:13)
      at Object.async.each (/Users/newuser/w/citiesense/search/node_modules/webpack/node_modules/async/lib/async.js:121:9)
      at Tapable.emitFiles (/Users/newuser/w/citiesense/search/node_modules/webpack/lib/Compiler.js:234:20)
      at /Users/newuser/w/citiesense/search/node_modules/webpack/node_modules/mkdirp/index.js:48:26
      at Object.oncomplete (fs.js:108:15)
// My config
  plugins.push(
    new CompressionPlugin({
        asset: "{file}.gz",
        algorithm: "gzip",
        regExp: /\.js$|\.html$/,
        threshold: 10240,
        minRatio: 0.8
    })
  );

Compressing files copied by 'copy-webpack-plugin'

Hello,

This is my setup:

let CompressionPlugin = require('compression-webpack-plugin');
let CopyWebpackPlugin = require('copy-webpack-plugin');
...
        new CopyWebpackPlugin([{ from: 'src/assets', to: 'assets' }]),

        new CompressionPlugin({
            asset: '[path].gz',
            algorithm: 'gzip',
            test:  /\.(js|css|map|po)$/,
            // threshold: 10240,
            minRatio: 10  // 0.8
        }),

The problem is that .po files, which are in src/assets/translations, and which are copied by the CopyWebpackPlugin don't get compressed by the CompressionPlugin.
Not sure who's plugin fault it is. :)
Is it possible to get it work as intended?

Thanks!

what is for?

Hello,I want to ask that what's this plugin for?
As the web server have the functionality to serve files in a compressed format,is it necessary to use this plugin to convert the file format?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.