embroider-build / embroider

Compiling Ember apps into spec-compliant, modern Javascript.
MIT License
337 stars 136 forks source link

"Class extends value #<Object> is not a constructor" Only on certain browsers. #1166

Closed x8BitRain closed 2 years ago

x8BitRain commented 2 years ago

I've got this weird issue with an ember 3.26.1 app built with embroider.

It's always the same error too.

Uncaught TypeError: Class extends value #<Object> is not a constructor or null
    at r._activateAdapter (chunk.76b4890494d46a1dd978.js:2:900357)
    at r.activateAdapters (chunk.76b4890494d46a1dd978.js:2:899833)
    at new a (chunk.76b4890494d46a1dd978.js:2:899528)
    at new r (chunk.9db9c707afb95dffe1e0.js:1:1072663)
    at Function.create (core_object.js:679:1)
    at v.create (index.js:539:1)
    at index.js:358:1
    at l (index.js:282:1)
    at a.lookup (index.js:143:1)
    at e.lookup (container_proxy.js:81:1)

ember-cli-build.js

const EmberApp = require('ember-cli/lib/broccoli/ember-app');
const env = EmberApp.env();
const config = require('./config/environment')(env);
const isProduction = env === 'production';
const isTestBuild = env === 'test';
const { V1Addon } = require('@embroider/compat');
const { forceIncludeModule } = require('@embroider/compat/src/compat-utils');

class EmberDataCompatAdapter extends V1Addon {
  get packageMeta() {
    return forceIncludeModule(super.packageMeta, './-private');
  }
}

module.exports = function (defaults) {
  const app = new EmberApp(defaults, {
    sourcemaps: {
      enabled: isProduction,
    },
    fingerprint: {
      extensions: [
        'js',
        'css',
        'png',
        'jpg',
        'gif',
        'svg',
        'ttf',
        'woff',
        'woff2',
      ],
    },
    tests: isTestBuild,
    hinting: isTestBuild,
    babel: {
      plugins: [
        require.resolve('ember-auto-import/babel-plugin'),
        '@babel/plugin-proposal-object-rest-spread',
        '@babel/plugin-proposal-nullish-coalescing-operator',
        '@babel/plugin-proposal-optional-chaining',
      ],
    },
    autoImport: {
      alias: {
        // when the app tries to import from "plotly.js", use
        // the real package "plotly.js-basic-dist" instead.
        'clipboard-copy': 'clipboard-copy/index.js',
      },
    },
    inlineContent: {
      symbols: 'vendor/inline/symbols.svg',
    },
    postcssOptions: {
      compile: {
        extension: 'scss',
        enabled: true,
        parser: require('postcss-scss'),
        plugins: [
          {
            module: require('@csstools/postcss-sass'),
            options: {
              includePaths: ['node_modules/tachyons-sass'],
            },
          },
          {
            module: require('postcss-import'),
            options: {
              path: [
                'node_modules/bootstrap/dist/css',
                'node_modules/nprogress',
                'vendor/flags/css',
              ],
            },
          },
        ],
      },
    },
  });

  app.options.postcssOptions.compile.plugins.push({
    module: require('@fullhuman/postcss-purgecss'),
    options: {
      content: ['./app/index.html', './app/**/*.hbs', './app/**/*.js'],
    },
  });

  if (config.gtagId) {
    app.options.inlineContent.gtag = {
      file: 'vendor/inline/gtag.js',
      postProcess: (content) =>
        content.replace(/\{\{GTAG_ID\}\}/g, config.gtagId),
    };
  }

  if (config.fbqId) {
    app.options.inlineContent.fbq = {
      file: 'vendor/inline/fbq.js',
      postProcess: (content) =>
        content.replace(/\{\{FBQ_ID\}\}/g, config.fbqId),
    };
  }

  if (config.rewardfulId) {
    app.options.inlineContent.rewardful = {
      file: 'vendor/inline/rewardful.html',
      postProcess: (content) =>
        content.replace(/\{\{REWARDFUL_ID\}\}/g, config.rewardfulId),
    };
  }

  const { Webpack } = require('@embroider/webpack');
  return require('@embroider/compat').compatBuild(app, Webpack, {
    staticAddonTestSupportTrees: true,
    staticAddonTrees: true,
    staticHelpers: true,
    staticModifiers: false,
    staticComponents: true,
    compatAdapters: new Map([
      ['@ember-data/model', EmberDataCompatAdapter],
      ['@ember-data/record-data', EmberDataCompatAdapter],
    ]),
    skipBabel: [
      {
        package: 'qunit',
      },
      {
        package: 'sinon',
      },
    ],
  });
};

package.json

{
  "name": "web",
  "version": "0.0.1",
  "description": "Web App",
  "repository": "",
  "license": "MIT",
  "author": "KUNDI",
  "directories": {
    "doc": "doc",
    "test": "tests"
  },
  "private": true,
  "scripts": {
    "build": "ember build --environment=production",
    "format:hbs": "prettier **/*.hbs --write",
    "lint": "npm-run-all --aggregate-output --continue-on-error --parallel 'lint:!(fix)'",
    "lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix",
    "lint:hbs": "ember-template-lint .",
    "lint:hbs:fix": "ember-template-lint . --fix",
    "lint:js": "eslint . --cache",
    "lint:js:fix": "eslint . --fix",
    "lint:deps": "ember dependency-lint",
    "lint:components": "./node_modules/.bin/ember-unused-components",
    "start": "ember serve",
    "test": "npm-run-all lint test:*",
    "test:ember": "percy exec -- ember test"
  },
  "simple-git-hooks": {
    "pre-commit": "yarn lint:hbs:fix && yarn lint:js:fix"
  },
  "engines": {
    "node": ">=v14"
  },
  "ember": {
    "edition": "octane"
  },
  "devDependencies": {
    "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3",
    "@babel/plugin-proposal-object-rest-spread": "^7.9.6",
    "@babel/plugin-proposal-optional-chaining": "^7.9.0",
    "@csstools/postcss-sass": "https://github.com/sinankeskin/postcss-sass.git",
    "@ember/optional-features": "^2.0.0",
    "@ember/render-modifiers": "^1.0.2",
    "@ember/test-helpers": "^2.6.0",
    "@embroider/compat": "^1.5.0",
    "@embroider/core": "^1.5.0",
    "@embroider/router": "^1.5.0",
    "@embroider/webpack": "^1.5.0",
    "@fullhuman/postcss-purgecss": "^4.1.3",
    "@glimmer/component": "^1.0.4",
    "@glimmer/tracking": "^1.0.4",
    "@html-next/vertical-collection": "^2.0.0",
    "@percy/cli": "^1.0.0-beta.47",
    "@percy/ember": "^3.0.0",
    "active-model-adapter": "4.0.0",
    "babel-eslint": "^10.1.0",
    "bootstrap": "3.3.4",
    "broccoli-asset-rev": "^3.0.0",
    "chart.js": "^3.1.0",
    "chartjs-adapter-date-fns": "^2.0.0",
    "date-fns": "^2.17.0",
    "diff": "^5.0.0",
    "ember-ajax-fetch": "^1.0.2",
    "ember-attacher": "^1.2.3",
    "ember-auto-import": "^2.4.0",
    "ember-awesome-macros": "6.0.0",
    "ember-cli": "~3.26.1",
    "ember-cli-app-version": "^5.0.0",
    "ember-cli-babel": "^7.26.3",
    "ember-cli-dependency-checker": "^3.2.0",
    "ember-cli-dependency-lint": "^2.0.0",
    "ember-cli-deploy": "1.0.2",
    "ember-cli-deploy-build": "2.0.0",
    "ember-cli-deploy-display-revisions": "^2.1.2",
    "ember-cli-deploy-gzip": "^2.0.0",
    "ember-cli-deploy-manifest": "^2.0.0",
    "ember-cli-deploy-revision-data": "1.0.0",
    "ember-cli-deprecation-workflow": "^2.0.0",
    "ember-cli-dotenv": "^3.1.0",
    "ember-cli-htmlbars": "^6.0.0",
    "ember-cli-inject-live-reload": "^2.0.2",
    "ember-cli-inline-content": "^0.4.1",
    "ember-cli-mirage": "^2.4.0",
    "ember-cli-notifications": "^8.0.0",
    "ember-cli-postcss": "^8.0.0",
    "ember-cli-sri": "^2.1.1",
    "ember-cli-string-helpers": "^6.0.1",
    "ember-cli-terser": "^4.0.0",
    "ember-cli-update": "^1.0.0",
    "ember-click-outside": "^3.0.0",
    "ember-composable-helpers": "^5.0.0",
    "ember-concurrency": "^2.0.1",
    "ember-cp-validations": "^4.0.0-beta.10",
    "ember-data": "^3.17.0",
    "ember-decorators": "^6.1.1",
    "ember-drag-drop": "git+https://github.com/jacobq/ember-drag-drop.git#f8b933241bf4d38130e96c33b5426e1e7286fcc9",
    "ember-element-helper": "^0.6.0",
    "ember-event-helpers": "^0.1.1",
    "ember-export-application-global": "^2.0.1",
    "ember-fetch": "^8.0.2",
    "ember-file-upload": "^4.0.0",
    "ember-group-by": "0.0.6",
    "ember-in-viewport": "^4.0.0",
    "ember-inflector": "^4.0.1",
    "ember-keyboard": "^7.0.0",
    "ember-load-initializers": "^2.1.1",
    "ember-local-storage-decorator": "^0.3.0",
    "ember-maybe-import-regenerator": "^1.0.0",
    "ember-metrics": "^1.4.2",
    "ember-modal-dialog": "^3.0.1",
    "ember-modifier": "^3.0.0",
    "ember-page-title": "^7.0.0",
    "ember-phone-input": "^6.0.0",
    "ember-power-select": "git+https://github.com/cibernox/ember-power-select.git",
    "ember-qunit": "^5.1.4",
    "ember-radio-button": "2.0.1",
    "ember-resolver": "^8.0.2",
    "ember-sinon": "^5.0.0",
    "ember-source": "~3.26.1",
    "ember-style-modifier": "^0.7.0",
    "ember-template-lint": "^4.0.0",
    "ember-template-lint-plugin-prettier": "^4.0.0",
    "ember-test-selectors": "^6.0.0",
    "ember-tether": "^2.0.0",
    "ember-text-highlight": "^1.2.3",
    "ember-truth-helpers": "^3.0.0",
    "ember-unused-components": "^1.2.0",
    "ember-uuid": "2.1.0",
    "ember-wormhole": "^0.6.0",
    "eslint": "^7.23.0",
    "eslint-config-prettier": "^8.1.0",
    "eslint-plugin-ember": "^10.5.9",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-prettier": "^4.0.0",
    "husky": "^7.0.1",
    "js-md5": "^0.7.3",
    "jstz": "^2.1.1",
    "loader.js": "^4.7.0",
    "lodash-es": "^4.17.20",
    "miragejs": "^0.1.43",
    "npm-run-all": "^4.1.5",
    "nprogress": "^0.2.0",
    "postcss-import": "^14.0.0",
    "postcss-scss": "^3.0.4",
    "prettier": "^2.2.1",
    "pretty-quick": "^3.1.0",
    "punycode": "^2.1.1",
    "qunit": "^2.18.0",
    "qunit-dom": "^2.0.0",
    "rollbar": "^2.19.3",
    "simple-git-hooks": "^2.7.0",
    "sinon": "^13.0.1",
    "webpack": "^5.69.1"
  },
  "resolutions": {
    "@ember/render-modifiers": "^1.0.0",
    "@embroider/util": "^1.5.0",
    "ember-assign-helper": "0.4.0",
    "ember-basic-dropdown": "^4.0.0",
    "ember-modifier": "^3.0.0",
    "ember-raf-scheduler": "^0.2.0",
    "ember-wormhole": "^0.6.0"
  },
  "dependencies": {
    "clipboard-copy": "^4.0.1"
  }
}

Example:

https://user-images.githubusercontent.com/15372551/158552701-a81ec67e-30e2-4509-a10f-20ebeb8dfa11.mp4

🙏 🙏

ef4 commented 2 years ago

This looks like it's probably a production build? Those don't have source maps turned on by default under embroider. Please turn them on like this:

 return require('@embroider/compat').compatBuild(app, Webpack, {
    packagerOptions: {
      webpackConfig: {
        devtool: 'source-map'
      }
    }
  });

That should give you a better stack trace. Please share that stack trace, and also click through the stack trace to see the code around the site of the exception and share that too.

x8BitRain commented 2 years ago

Thanks for the tip, it revealed more about the error, I now see an error related to ember-metrics:

Uncaught Error: Could not find module `ember-metrics/metrics-adapters/mixpanel` imported from `web-app/initializers/metrics`
    at missingModule (vendor.js:259:11)
    at findModule (vendor.js:270:7)
    at Module.findDeps (vendor.js:180:24)
    at findModule (vendor.js:274:11)
    at requireModule (vendor.js:36:15)
    at r (vendor.js:188:14)
    at resolveInitializer (vendor.js:152989:39)
    at registerInitializers (vendor.js:153010:23)
    at loadInitializers (vendor.js:153051:5)
    at Module.callback (web-app.js:628:38)

I found this branch that re-exports the metrics adapters so embroider understands them. https://github.com/Windvis/ember-metrics/commit/4b2e2566c8bd594e0dd4105153211603e28fc4fc

Now it's working again, thanks! 🍾