marcj / css-element-queries

CSS Element-Queries aka Container Queries. High-speed element dimension/media queries in valid css.
http://marcj.github.io/css-element-queries/
MIT License
4.27k stars 487 forks source link

Fixing to work with more recent versions of TypeScript #243

Closed Pauan closed 5 years ago

Pauan commented 5 years ago

Without this change I get this error from TypeScript:

Module '"node_modules/css-element-queries/src/ResizeSensor"' has no default export.

24 import ResizeSensor from "css-element-queries/src/ResizeSensor";
          ~~~~~~~~~~~~
marcj commented 5 years ago

Thanks!

astegmaier commented 5 years ago

I think this change might have broken something (or maybe it's my ignorance?). I can see that it does indeed enable imports along the lines of:

import ResizeSensor from "css-element-queries/src/ResizeSensor";

However, after the import, when I go to actually create a instantiate the class like this:

new ResizeSensor(...);

It compiles fine, but I get this error at runtime.

Uncaught TypeError: ResizeSensor_1.default is not a constructor

@Pauan - do you see the same problem? Is there some other way of creating a resize sensor that I should try instead of new?

coalman commented 5 years ago

@astegmaier You might need to change your import to look like:

import * as ResizeSensor from "css-element-queries/src/ResizeSensor";
Pauan commented 5 years ago

@astegmaier How are you building your project? You have to bundle your project with Webpack or Parcel (it will handle the import logic correctly).

astegmaier commented 5 years ago

Thanks for the suggestion @coalman It worked (sort of). When I change my imports to:

import * as ResizeSensor from "css-element-queries/src/ResizeSensor";

... and I look at my line where I'm instantiating the class (new ResizeSensor(...)), VSCode will complain:

Cannot use 'new' with an expression whose type lacks a call or construct signature.

However, if I ignore this error (by changing it to new (ResizeSensor as any)(...)), then webpack will compile it fine. If I do the reverse, and use my original import statement:

import * as ResizeSensor from "css-element-queries/src/ResizeSensor";

...then VSCode stops complaining (even after removing the any assertion), but webpack gives the same error that VSCode used to give. Very strange. Does anyone have ideas about why this might be happening?

@Pauan I'm building using ts-loader for webpack, and my tsconfig.json file looks like this:

{
  "compilerOptions": {
    /* Basic Options */
    "target": "es5",
    "module": "commonjs",
    "lib": ["dom", "es5", "es2015", "es2017.object", "es2016.array.include"],
    "jsx": "react",
    "sourceMap": true,
    "strict": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "moduleResolution": "node",
    "typeRoots": [
      "./node_modules/@types",
      "./src/typings"
    ],
    "types": [
      "bootstrap",
      "jquery",
      "jquery-toast-plugin",
      "jqueryui",
      "prop-types",
      "react",
      "react-dom",
      "react-redux"
    ],
  }
}
marcj commented 5 years ago

I'm not sure about that, but I can tell that I'll write on css-element-queries v2.0 which is written completely in TypeScript at the end of this month, so this issue will definitely go away then.

Pauan commented 5 years ago

@astegmaier You can't use import * as ResizeSensor from "...", because ResizeSensor.js uses module.exports = ... (which is equivalent to export default ... with ES6 modules). So import ResizeSensor from "..." is correct.

Taking a look at your tsconfig.json, I see you're using "module": "commonjs", but that should be "module": "esnext" instead:

{
    "compilerOptions": {
        "module": "esnext",
        "esModuleInterop": true,
    }
}

Basically, by using "module": "commonjs", you're telling TypeScript to compile your modules into CommonJS. But you don't want that, you want TypeScript to compile into ES6 modules, and then Webpack will correctly compile those ES6 modules.

(As a bonus, this also allows Webpack to tree shake unused functions in your code; Webpack only does tree shaking with ES6 modules).