Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(service-worker): minify SW script (+ sourcemaps) #27490

Open
gkalpak opened this issue Dec 5, 2018 · 6 comments
Open

feat(service-worker): minify SW script (+ sourcemaps) #27490

gkalpak opened this issue Dec 5, 2018 · 6 comments
Labels
area: service-worker Issues related to the @angular/service-worker package feature Issue that requests a new feature

Comments

@gkalpak
Copy link
Member

gkalpak commented Dec 5, 2018

Currently, the SW script generated by @angular/service-worker is unminified. This was intentional so that it was easier to debug and the stack traces (that people having issues might provide) would be easier to interpret. This is not a major concern, since the SW scripts are aggressively cached by the browser and downloaded/parsed/executed out-of-band with page rendering.

Nonetheless, now that the SW is more stable, it may make sense to minify it for production (with sourcemaps for debugging).

(Related/Duplicate issue: angular/angular-cli#11538)

@gkalpak gkalpak added the area: service-worker Issues related to the @angular/service-worker package label Dec 5, 2018
@gkalpak gkalpak added this to the v8-candidates milestone Dec 5, 2018
@gkalpak gkalpak changed the title feat(service-worker): minify Sw script (+ sourcemaps) feat(service-worker): minify SW script (+ sourcemaps) Dec 5, 2018
@alxhub alxhub added the feature Issue that requests a new feature label Dec 6, 2018
@muuvmuuv
Copy link

muuvmuuv commented Jul 2, 2020

Would love to see this in the next release. I have set up a minifier myself for some files:

  • index.html
  • ngsw-worker.js
  • worker-basic.min.js (.min but isn't minified ^^)
  • safety-worker.js (same content as worker-basic?)
  • manifest.webmanifest
  • ngsw.json
Minify code
const htmlMinifier = require('html-minifier-terser').minify
const jsMinifier = require('terser').minify

function minifyHtml(contents) {
  return htmlMinifier(contents, {
    collapseBooleanAttributes: true,
    collapseWhitespace: true,
    decodeEntities: true,
    includeAutoGeneratedTags: false,
    minifyCSS: true,
    minifyJS: true,
    minifyURLs: true,
    processScripts: ['text/html'],
    removeAttributeQuotes: true,
    removeComments: true,
    removeOptionalTags: true,
    removeRedundantAttributes: true,
    removeScriptTypeAttributes: true,
    removeStyleLinkTypeAttributes: true,
    trimCustomFragments: true,
    useShortDoctype: true,
  })
}

function minifyJs(contents) {
  return jsMinifier(contents, {
    keep_classnames: true,
    keep_fnames: true,
    output: {
      comments: '',
    },
  }).code
}

function minifyJson(contents) {
  if (contents.$schema) {
    // $schema is only needed for autocompletion
    delete contents.$schema
  }
  return JSON.stringify(contents)
}

@blasco
Copy link

blasco commented Jul 20, 2020

I'm struggling creating my own minification script. I was traying to use the cli version of terser, but --compress and --mangle seem to break the code. Could you give an example on how to use you minifying script @muuvmuuv ?

@muuvmuuv
Copy link

@blasco I have created a NodeJs script that gets the above files contents, uses the above minifier and overrides them. I will post my script tomorrow but it is pretty complex.

@muuvmuuv
Copy link

@blasco

NodeJS script to minify files post build:

#!/usr/bin/env node

const fs = require('fs')
const path = require('path')
const { cyan, dim, green, red } = require('kleur')

const { projectRoot, minifyHtml, minifyJs, minifyJson } = require('./utils')
const dist = path.join(projectRoot, 'dist', 'aqua')

const input = {
  html: ['index.html'],
  js: ['ngsw-worker.js', 'worker-basic.min.js', 'safety-worker.js'],
  json: ['manifest.webmanifest', 'ngsw.json'],
}

function minify(file, ext) {
  const filePath = path.join(dist, file)
  let minified,
    contents = ''

  try {
    contents = fs.readFileSync(filePath, { encoding: 'utf-8' })
  } catch (error) {
    console.log(red('File not found ' + filePath))
    return
  }

  switch (ext) {
    case 'html':
      minified = minifyHtml(contents)
      break
    case 'js':
      minified = minifyJs(contents)
      break
    case 'json':
      minified = minifyJson(JSON.parse(contents))
      break
    default:
      throw new Error('Unknown extension: ' + ext)
  }

  fs.writeFileSync(filePath, minified)
}

console.log(cyan('Minifying files...'))

Object.entries(input).forEach(([ext, files]) => {
  files.forEach((file) => {
    console.log(dim('> File ' + file))
    minify(file, ext)
  })
})

console.log(green('Done!'))

In package json:

    "build": "run-s build:*",
    "build:ng": "ng build --prod",
    "build:min": "node scripts/minify.js",

@tomdev9
Copy link

tomdev9 commented Sep 10, 2020

@muuvmuuv can u add method from ./utils ? to run your minify.js cript ? thanks

@muuvmuuv
Copy link

Here you go @tomastalian : https://gist.github.com/muuvmuuv/3f8fae0c12cc0859195c1be981c88a19

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: service-worker Issues related to the @angular/service-worker package feature Issue that requests a new feature
Projects
None yet
Development

No branches or pull requests

6 participants