arielsalminen / vue-design-system

An open source tool for building UI Design Systems with Vue.js
https://vueds.com
MIT License
2.17k stars 224 forks source link

ERROR in system/system.js from UglifyJs Unexpected token: punc (() [system/system.js:50506,9] #120

Closed michaelpumo closed 5 years ago

michaelpumo commented 5 years ago

Hi

I upgraded to and am running latest VDS 3.5.2 and when I run npm run build:system I get the stated error.

ERROR in system/system.js from UglifyJs Unexpected token: punc (() [system/system.js:50506,9]

Stopping me dead in my tracks.

Thanks.

arielsalminen commented 5 years ago

@michaelpumo Very hard to track down what might be the issue without seeing your full configuration/codebase. If you take a clean clone of Vue Design System, run npm install and then npm run build:system does that work? (it should as Travis tests would immediately fail if not!)

Now, if that works, I’m going to need more details and/or the access to the code base to be able to tell what in your own configuration could be causing this.

arielsalminen commented 5 years ago

@michaelpumo The only thing that comes to my mind is that maybe the code isn’t getting converted to ES5 before minifying. I wonder if you’d be able to provide me a simplified test case so I could help?

arielsalminen commented 5 years ago

@michaelpumo Can you also share your package.json source and webpack.system.conf.js ?

michaelpumo commented 5 years ago

Hi @viljamis - please see the following files:

package.json

{
  "name": "fp-design-system",
  "version": "3.5.2",
  "description": "Vue Design System is an open-source tool for building Design Systems with Vue.js",
  "author": "viljamis <me@viljamis.com>",
  "main": "dist/system/system.js",
  "files": [
    "dist/system"
  ],
  "homepage": "https://vueds.com",
  "private": true,
  "license": "MIT",
  "scripts": {
    "dev": "webpack-dev-server --inline --config ./build/webpack.dev.conf.js",
    "start": "npm-run-all --parallel styleguide theo:onchange theo dev",
    "unit": "jest --config ./test/unit/jest.conf.js --coverage",
    "build": "npm-run-all theo node:build",
    "build:app": "npm run build",
    "build:system": "npm-run-all theo node:build:system",
    "build:docs": "npm-run-all theo styleguide:build",
    "lint": "eslint '**/*.{js,vue}' --cache",
    "node:build": "node ./build/build.js",
    "node:build:system": "node ./build/build-system.js",
    "styleguide": "vue-styleguidist server --open --config ./config/docs.config.js",
    "styleguide:build": "vue-styleguidist build --config ./config/docs.config.js",
    "theo": "theo ./src/tokens/tokens.yml --transform web --format map.scss,scss,raw.json,json --dest ./src/assets/tokens",
    "theo:onchange": "onchange \"./src/tokens/*.yml\" -- npm run theo",
    "test": "npm-run-all theo unit",
    "precommit": "pretty-quick --staged"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/viljamis/vue-design-system.git"
  },
  "keywords": [
    "vue design system",
    "design system",
    "vue.js",
    "vue",
    "design",
    "system"
  ],
  "babel": {
    "presets": [
      "@babel/preset-env"
    ],
    "plugins": [
      "@babel/plugin-syntax-dynamic-import",
      "@babel/plugin-proposal-class-properties",
      "@babel/plugin-proposal-object-rest-spread",
      "@babel/plugin-transform-runtime"
    ],
    "env": {
      "test": {
        "presets": [
          "@babel/preset-env"
        ],
        "plugins": [
          "@babel/plugin-syntax-dynamic-import",
          "@babel/plugin-proposal-class-properties",
          "@babel/plugin-proposal-object-rest-spread"
        ]
      }
    }
  },
  "eslintConfig": {
    "extends": [
      "eslint:recommended",
      "plugin:vue/essential"
    ],
    "env": {
      "browser": true,
      "node": true
    },
    "rules": {
      "indent": [
        "error",
        2
      ],
      "vue/no-unused-vars": "error",
      "quotes": [
        "error",
        "double"
      ],
      "no-extra-semi": "off",
      "semi": [
        "error",
        "never"
      ],
      "semi-style": [
        "error",
        "last"
      ],
      "no-console": "off"
    },
    "parserOptions": {
      "sourceType": "module",
      "ecmaVersion": 8,
      "ecmaFeatures": {
        "jsx": true
      }
    }
  },
  "dependencies": {
    "choices.js": "^3.0.4",
    "date-fns": "^1.29.0",
    "gsap": "^2.0.2",
    "jump.js": "^1.0.2",
    "lazysizes": "^4.1.3",
    "lodash": "^4.17.11",
    "mini-css-extract-plugin": "^0.4.3",
    "postcss-import": "^12.0.0",
    "postcss-loader": "^3.0.0",
    "postcss-safe-parser": "^4.0.1",
    "postcss-url": "^8.0.0",
    "swiper": "^4.4.1",
    "tinycolor2": "^1.4.1",
    "v-lazy-image": "^1.2.2",
    "vee-validate": "^2.0.9",
    "vue": "^2.5.17",
    "vue-flickity": "^1.1.2",
    "vue-lodash": "^2.0.0",
    "vue-meta": "^1.5.5",
    "vue-router": "^3.0.1",
    "vue-scrollmonitor": "^0.1.0",
    "vue-upload-component": "^2.8.14",
    "vueinview": "^1.0.5",
    "vuex": "^3.0.1",
    "webfontloader": "^1.6.28"
  },
  "devDependencies": {
    "@babel/cli": "^7.1.2",
    "@babel/core": "^7.1.2",
    "@babel/plugin-proposal-class-properties": "^7.1.0",
    "@babel/plugin-proposal-object-rest-spread": "^7.0.0",
    "@babel/plugin-syntax-dynamic-import": "^7.0.0",
    "@babel/plugin-transform-runtime": "^7.1.0",
    "@babel/preset-env": "^7.1.0",
    "@babel/register": "^7.0.0",
    "@vue/test-utils": "^1.0.0-beta.25",
    "autoprefixer": "^9.1.5",
    "babel-core": "^7.0.0-bridge.0",
    "babel-eslint": "^10.0.1",
    "babel-jest": "^23.6.0",
    "babel-loader": "^8.0.4",
    "chalk": "^2.4.1",
    "codemirror": "^5.40.2",
    "compression-webpack-plugin": "^2.0.0",
    "copy-webpack-plugin": "^4.5.2",
    "css-loader": "^1.0.0",
    "eslint": "^5.6.1",
    "eslint-plugin-compat": "^2.5.1",
    "eslint-plugin-es5": "^1.3.1",
    "eslint-plugin-import": "^2.14.0",
    "eslint-plugin-vue": "^4.7.1",
    "file-loader": "^2.0.0",
    "friendly-errors-webpack-plugin": "^1.7.0",
    "html-loader": "^0.5.5",
    "html-webpack-plugin": "^3.2.0",
    "http-proxy-middleware": "^0.19.0",
    "husky": "^0.14.3",
    "jest": "^23.6.0",
    "jest-serializer-vue": "^2.0.2",
    "node-notifier": "^5.2.1",
    "node-sass": "^4.9.3",
    "npm-run-all": "^4.1.3",
    "onchange": "^4.1.0",
    "optimize-css-assets-webpack-plugin": "^5.0.1",
    "ora": "^3.0.0",
    "portfinder": "^1.0.17",
    "prettier": "^1.12.0",
    "pretty-quick": "^1.7.0",
    "rimraf": "^2.6.0",
    "sass-loader": "^7.1.0",
    "sass-resources-loader": "^1.3.3",
    "semver": "^5.5.1",
    "shelljs": "^0.8.2",
    "style-loader": "^0.23.0",
    "theo": "^8.0.0-beta.2",
    "uglifyjs-webpack-plugin": "^2.0.1",
    "url-loader": "^1.1.1",
    "vue-jest": "^2.6.0",
    "vue-loader": "^15.4.2",
    "vue-style-loader": "^4.1.2",
    "vue-styleguidist": "^1.8.9",
    "vue-template-compiler": "^2.5.17",
    "webpack": "^4.20.2",
    "webpack-bundle-analyzer": "^3.0.2",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.9",
    "webpack-merge": "^4.1.4",
    "webpack-merge-and-include-globally": "^2.0.11"
  },
  "engines": {
    "node": ">= 8.6.0",
    "npm": ">= 3.0.0"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not Explorer > 0",
    "IE 11",
    "not ExplorerMobile > 0",
    "not BlackBerry > 0",
    "not OperaMini all",
    "not OperaMobile > 0"
  ]
}

webpack.system.conf.js

"use strict"
const utils = require("./utils")
const webpack = require("webpack")
const path = require("path")
const config = require("../config")
const merge = require("webpack-merge")
const baseWebpackConfig = require("./webpack.base.conf")
const MergeWebpackPlugin = require("webpack-merge-and-include-globally")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const OptimizeCSSPlugin = require("optimize-css-assets-webpack-plugin")
const UglifyJsPlugin = require("uglifyjs-webpack-plugin")
const CopyWebpackPlugin = require("copy-webpack-plugin")
const SafeParser = require("postcss-safe-parser")

const env = require("../config/prod.env")

baseWebpackConfig.entry = {
  system: ["./src/system.js"],
}

const webpackConfig = merge(baseWebpackConfig, {
  module: {
    rules: utils.styleLoaders({
      sourceMap: config.system.productionSourceMap,
      extract: true,
      usePostCSS: true,
    }),
  },
  devtool: config.build.productionSourceMap ? config.system.devtool : false,
  output: {
    path: config.system.assetsRoot,
    filename: utils.assetsSystemPath("[name].js"),
    library: "[name]",
    libraryTarget: config.system.libraryTarget,
  },
  performance: {
    hints: config.system.performanceHints,
  },
  plugins: [
    // http://vuejs.github.io/vue-loader/en/workflow/production.html
    new webpack.DefinePlugin({
      "process.env": env,
    }),
    new UglifyJsPlugin({
      uglifyOptions: {
        compress: {
          warnings: false,
        },
      },
      sourceMap: config.system.productionSourceMap,
      parallel: true,
    }),
    // extract css into its own file
    new MiniCssExtractPlugin({
      filename: utils.assetsSystemPath("[name].css"),
    }),
    // Compress extracted CSS. We are using this plugin so that possible
    // duplicated CSS from different components can be deduped.
    new OptimizeCSSPlugin({
      cssProcessorOptions: { parser: SafeParser },
    }),
    // keep module.id stable when vendor modules does not change
    new webpack.HashedModuleIdsPlugin(),
    // enable scope hoisting
    new webpack.optimize.ModuleConcatenationPlugin(),
    // Copy and merge Sass tokens and system utilities as well
    new MergeWebpackPlugin({
      files: {
        [utils.assetsSystemPath("system.utils.scss")]: [
          "./src/assets/tokens/tokens.scss",
          "./src/styles/_spacing.scss",
          "./src/styles/_mixins.scss",
          "./src/styles/_functions.scss",
        ],
      },
    }),
    // copy custom static assets
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, "../src/assets"),
        to: config.system.assetsSubDirectory,
        ignore: [".*"],
      },
    ]),
  ],
})

if (config.system.productionGzip) {
  const CompressionWebpackPlugin = require("compression-webpack-plugin")

  webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
      asset: "[path].gz[query]",
      algorithm: "gzip",
      test: new RegExp("\\.(" + config.system.productionGzipExtensions.join("|") + ")$"),
      threshold: 10240,
      minRatio: 0.8,
    })
  )
}

if (config.system.bundleAnalyzerReport) {
  const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin
  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

module.exports = webpackConfig
arielsalminen commented 5 years ago

@michaelpumo Everything looks fine in these files. Tested your package.json setup and it’s compiling ok for me. I think this is somehow related to your Babel setup. Did the error message show any other details or just that one line?

arielsalminen commented 5 years ago

@michaelpumo this probably won’t do any difference, but have you tried running rm -rf node_modules && npm install?

michaelpumo commented 5 years ago

I've tried from a blank state but the same problem occurs.

It was just that one line of error and it fails to generate anything.

The Babel config was left as-is in the package.json, so I'm not sure why this would be happening?

arielsalminen commented 5 years ago

@michaelpumo So you mean doing a clean clone of the repo to another dir, then running npm install and then npm run build:system fails too for you?

arielsalminen commented 5 years ago

@michaelpumo Would you be able to provide a bit more details about your system? The operating system + version, Node version & shell you are using (if relevant)?

michaelpumo commented 5 years ago

I can confirm that a fresh install works and builds as expected.

It seems then it's an issue with my own code...but I have no idea what would be causing it.

I'm using macOS High Sierra and Node v10.11.0

Are there any obvious things that could trip this up? I'm able to run the project just fine. I just can't do the build.

arielsalminen commented 5 years ago

@michaelpumo Hmm. Can’t think of anything obvious right now since your config looks fine. Seems like Uglify doesn’t understand something in your code. I’d personally maybe try disabling/removing things until you find the culprit.

What does your src/system.js entry file look like? Maybe there’d be some pointers why this is happening: https://github.com/viljamis/vue-design-system/blob/master/src/system.js

michaelpumo commented 5 years ago

I have tracked down the culprit.

I am importing a package called vue-flickity. A wrapper for the Flickity library.

Within its node_modules folder, there is a single flickity.vue file and it's that which is imported.

However, it appears that the build command is unable to parse some es6 syntax within this file and it fails.

If I change:

export default {
  mounted () {
  }
}

...to...

export default {
  mounted: function () {
  }
}

...in the file...the system will build it correctly.

So it's not as though the component is doing anything wrong, it's just that it's written in es6.

But that's odd behaviour because my own components are written in es6 just the same way and they appear to cause me no issue.

Any idea what can be done about this problem and why / how it even happens?

arielsalminen commented 5 years ago

@michaelpumo I will do some testing today and report back :-)

arielsalminen commented 5 years ago

@michaelpumo Managed to reproduce this. Seems like babel isn’t working correctly in this case and isn’t doing anything to things included from node_modules. I don’t unfortunately have time to debug more today, but can help around the end of week if you’re unable to solve it.

arielsalminen commented 5 years ago

@michaelpumo Tracked it down to this breaking change in Uglify.js (Uglify does not support ES6 anymore): https://github.com/webpack-contrib/uglifyjs-webpack-plugin/blob/master/CHANGELOG.md#breaking-changes.

This comment made me found the changelog: https://github.com/webpack/webpack/issues/5858#issuecomment-423796350

I will release a new version with fix to this (and changing from Uglify to Terser https://github.com/webpack-contrib/terser-webpack-plugin) later today or tomorrow.

michaelpumo commented 5 years ago

Hi @viljamis, I've just been reading through - sorry for the delay.

Thanks for your investigations into the issue. Shame about Uglify not supporting ES6 (madness?!) but I fully support a switch that could help with this. If Terser is a breeze to drop in then that would be fantastic.

Thanks for all your hard work. Looking forward to the update!

arielsalminen commented 5 years ago

@michaelpumo The problem is now fixed in this branch: https://github.com/viljamis/vue-design-system/pull/122 would you be able to test with those changes if it fixes your issue as well before I make a release?

michaelpumo commented 5 years ago

Hi @viljamis I just cloned the repo and used my vue-flickity component. It appears to build just fine!

So that's good news all-around.

Question: is there any easy way to upgrade the VDS? I did it manually last time but it's very error-prone moving files around like that, especially when there are changes made here and there to tokens etc.

Thanks!

arielsalminen commented 5 years ago

@michaelpumo Not currently as this is meant to be more of a starting template to build upon. I will be looking into possibilities to make it easier in the future though.

I’ll close this as just merged the fix and publishing a new version!

michaelpumo commented 5 years ago

Thank you! I'm getting issues with Nuxt now, but I will file that in a new issue.