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

Uncaught TypeError: Color is not a function #434

Open
McLaynV opened this issue Jan 20, 2023 · 4 comments
Open

Uncaught TypeError: Color is not a function #434

McLaynV opened this issue Jan 20, 2023 · 4 comments

Comments

@McLaynV
Copy link
Contributor

McLaynV commented Jan 20, 2023

Hello,
I'm new to Javascript, so it is probably my problem, but I've spent a few evenings on this and wasn't able to google anything related, so here I am asking for help.

I have a simple Vue app with CSS handled by bulma. Here is a color picker and a function to change the primary color in bulma using bulma-css-vars:

<script setup lang="ts">
import { ColorUpdater } from 'bulma-css-vars';
import { ColorCallSet } from "bulma-css-vars/dist/types";
import { bulmaCssVariablesDefs } from "../bulma-generated/bulma-colors";

const colorUpdater = new ColorUpdater(bulmaCssVariablesDefs as ColorCallSet);

function setPrimaryColor(event: any) {
  const colorName = "primary";
  const color = event.target.value;

  colorUpdater.updateVarsInDocument(colorName, color);
}
</script>

<template>
  <div class="content">
    <label>Primary
      <input
        type="color"
        @change="setPrimaryColor"
        class="input is-primary"
      />
    </label>
  </div>
</template>

However, calling the setPrimaryColor function (when the <input> element value is changed or even calling colorUpdater.updateVarsInDocument(...) manually) causes the following error.

Uncaught TypeError: Color is not a function
    at stringToHsl (bulma-color-tools.js:90:30)
    at ColorUpdater.getUpdatedVars (color-updater.js:24:23)
    at ColorUpdater.updateVarsInDocument (color-updater.js:33:31)
    at setPrimaryColor (ColorPalette.vue:13:16)
    at callWithErrorHandling (runtime-core.esm-bundler.js:157:22)
    at callWithAsyncErrorHandling (runtime-core.esm-bundler.js:166:21)
    at HTMLInputElement.invoker (runtime-dom.esm-bundler.js:345:9)

const [h, s, l] = getHsl(Color(col)).color

export function stringToHsl(col) {
    const [h, s, l] = getHsl(Color(col)).color; // <<<< HERE IS THE ERROR THROWN IN Color(col)
    return { h, s, l };
}

I tried debugging in Chrome and playing with the Color object. My findings are here:

typeof Color: "object"
Color: Function
col: "#520f0f"
Color(col): <not available>
Color.default(col): Color2
Color.prototype(col): <not available>
Color('rgb(123,123,123)'): <not available>
Color({r:123, g:123, b:123}): <not available>
new Color(col): <not available>
Color.call(col): <not available>

I believe that Color.default(col) does the expected thing in my environment.

Could I have a different version of something? My package-lock.js says:

    "node_modules/bulma": {
      "version": "0.9.4",
      "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.9.4.tgz",
      "integrity": "sha512-86FlT5+1GrsgKbPLRRY7cGDg8fsJiP/jzTqXXVqiUZZ2aZT8uemEOHlU1CDU+TxklPEZ11HZNNWclRBBecP4CQ=="
    },
    "node_modules/bulma-css-vars": {
      "version": "0.8.0",
      "resolved": "https://registry.npmjs.org/bulma-css-vars/-/bulma-css-vars-0.8.0.tgz",
      "integrity": "sha512-PhhvuZcSPlnPvgWoo/8y8QAYHCCkW2gjCcVD5P/zIyNrKwzk+I4QdDpexKtzCF7TduNNP5DQGG8InulBe5TGtg==",
      "dev": true,
      "dependencies": {
        "color": "^4.2.1",
        "css": "^3.0.0",
        "mkdirp": "^1.0.4"
      },
      "bin": {
        "bulma-css-vars": "bin/bulma-css-vars.js"
      },
      "engines": {
        "node": ">= 10.0.0"
      },
      "peerDependencies": {
        "bulma": "^0.9.3"
      }
    },
    "node_modules/color": {
      "version": "4.2.3",
      "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
      "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
      "dev": true,
      "dependencies": {
        "color-convert": "^2.0.1",
        "color-string": "^1.9.0"
      },
      "engines": {
        "node": ">=12.5.0"
      }
    },

And my package.json:

  "dependencies": {
    "@fortawesome/fontawesome-free": "^6.2.1",
    "@pinia/testing": "^0.0.14",
    "@vueuse/core": "^7.7.0",
    "axios": "^0.26.0",
    "bulma": "^0.9.3",
    "pinia": "^2.0.11",
    "vue": "^3.2.31",
    "vue-router": "^4.0.13"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^2.2.4",
    "bulma-css-vars": "^0.8.0",
    "cypress": "^12.1.0",
    "eslint-plugin-cypress": "^2.12.1",
    "sass": "^1.49.9",
    "typescript": "^4.6.2",
    "vite": "^2.8.5",
    "vue-tsc": "^0.32.0"
  }
@wtho
Copy link
Owner

wtho commented Jan 21, 2023

Hey @McLaynV!
Is your project public? Would help me a lot if I could have a look at a reproduction of the error.

Anyways I haven't really worked in this bulma-css-vars in the past, even bulma hasn't seen much development in the last years.
If you just want to use ready-to-use components you can go for bulma, but if you want to use advanced features like css variables, looking into tailwind might be a good option.

That being said I'll have a look at the issue if you can share a reproduction.

@McLaynV
Copy link
Contributor Author

McLaynV commented Jan 21, 2023

Hello @wtho,
here is the branch of my testing project where I was experimenting with bulma-css-vars: https://github.com/McLaynV/vue-express-template/tree/colors-wip

Steps to reproduce:

BTW I also experienced the #167 issue (running on Windows 10 from IntelliJ Idea). Using npx bulma-css-vars --init worked as suggested by you in #167 (comment)
I'm mentioning it because it could (as well as this issue) also be related to having a different environment.

@McLaynV
Copy link
Contributor Author

McLaynV commented Jan 21, 2023

Anyways I haven't really worked in this bulma-css-vars in the past, even bulma hasn't seen much development in the last years. If you just want to use ready-to-use components you can go for bulma, but if you want to use advanced features like css variables, looking into tailwind might be a good option.

I decided to go for bulma as it was already in an example project I was starting from, and it seemed as a reasonably simple CSS framework with all the components predefined. Then I had a use case for CSS variables and that's how I found bulma-css-vars.

I'm looking at tailwindcss now and I like its prefixes syntax - the things like dark:, sm: and hover:. Other than that, I feel like I could make the components in plain Vue without tailwindcss with the same effort and less dependencies.

@kikuomax
Copy link

kikuomax commented Dec 5, 2023

I faced the same error while I was migrating from Webpack v4 to Vite. This was caused due to how import * as Color from 'color' was interpreted was different between TypeScript and Vite (esbuild or Rollup).

import * as Color from 'color'

In TypeScript, Color became a function:

function () { ... }

In Vite, Color became an object:

{ default: function () { ... } }

For now, I worked around the problem by adding the following Vite plugins to my vite.config.js:

import * as fs from 'node:fs'
import * as util from 'node:util'
import { defineConfig } from 'vite'

const readFile = util.promisify(fs.readFile)

export default defineConfig({
  plugins: [
    {
      // For development:
      //
      // patches access to `Color` in `bulma-css-vars`
      //
      //   `Color` → `Color.default`
      //
      // `color` is imported in `bulma-css-vars` as
      //
      //   import * as Color from 'color'
      //
      //   (https://github.com/wtho/bulma-css-vars/blob/892baa8dad6c5082367159c2605853d6a7973b51/lib/src/bulma-color-tools.ts#L1)
      //
      // this causes a compatibility issue between TypeScript and Vite (esbuild)
      // `Color` is a function in TypeScript, while it is an object like the
      // following in esbuild:
      //
      //   {
      //     default: function () { /* expected implementation of Color */ }
      //   }
      //
      // to call the expected function in esbuild, we have to extract `default`
      // from `Color`.
      //
      // it seems Vite bypasses `load` hooks for `node_modules` in development
      // mode, so we have to transform the results of esbuild
      name: 'transform-bulma-css-vars',
      transform(src, id) {
        if (id.includes('.vite/deps/bulma-css-vars.js')) {
          const transformed = src.replace(/(\W)Color\(/g, '$1Color.default(')
          return {
            code: transformed,
            map: null
          }
        }
      }
    },
    {
      // For production:
      //
      // while esbuild is used in development mode, @rollup/plugin-commonjs is
      // used in production mode. so we need a different plugin for production
      //
      // patches `bulma-color-tools.js` in `bulma-css-vars`
      //
      //   import * as Color from 'color'
      //     ↓
      //   import Color from 'color'
      //
      // in this way, Rollup can import Color as a function
      name: 'load-bulma-css-vars',
      async load(id) {
        if (id.includes('bulma-css-vars')
          && id.endsWith('bulma-color-tools.js'))
        {
          const src = await readFile(id, 'utf8')
          const replaced = src.replace(
            'import * as Color from \'color\'',
            'import Color from \'color\'',
          )
          return replaced
        }
      },
    },
  ],
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants