Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fabric.js with Typescript and Webpack: Canvas is not a constructor

I'm trying to use fabric.js with Typescript and Webpack aside some other modules in a Laravel 5.4 application that work fine in the browser. @types/fabric ist installed and Typescript behaves correct. New to Typescript as well as Webpack i tried some variants with no success.

The problem

result.js:198 Uncaught TypeError: __WEBPACK_IMPORTED_MODULE_1_fabric___default.a.Canvas is not a constructor

Variant A

code.ts

import fabric from "fabric";
const canvas = new fabric.Canvas('my-canvas');

result.js

var canvas = new __WEBPACK_IMPORTED_MODULE_1_fabric__default.a.Canvas('my-canvas');

WEBPACK_IMPORTED_MODULE_1_fabric__default requires WEBPACK_IMPORTED_MODULE_1_fabric which is an object with fabric as key.

const canvas = new fabric.fabric.Canvas('my-canvas');

would be working for Webpack but is not conform to type inspections.

Variant B

code.ts

import * as fabric from "fabric";
const canvas = new fabric.Canvas('my-canvas');

result.js

var canvas = new __WEBPACK_IMPORTED_MODULE_1_fabric__["Canvas"]('my-canvas');

WEBPACK_IMPORTED_MODULE_1_fabric contains an object with fabric as key so that the situation is like with variant A.

Variant C

code.ts

import {Canvas} from "fabric";
const canvas = new Canvas('my-canvas');

result.js

var canvas = new __WEBPACK_IMPORTED_MODULE_1_fabric__["Canvas"]('my-canvas');

At the end it is the same as with variant B.

excerpt of webpack.mix.js

   .webpackConfig({
    module: {
        rules: [
            {
                test: /\.js$/,
                loader: 'babel-loader',
                include: [
                    path.resolve('app/public/js'),
                    path.resolve('node_modules/countable')
                ],
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader',
                exclude: [
                    path.resolve('resources/assets/ts/components')
                ],
                options: {
                    loaders: {
                        'scss': 'vue-style-loader!css-loader!sass-loader',
                        'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax',
                    }
                }
            },
            {
                test: /\.tsx?$/,
                loader: 'ts-loader',
                exclude: /node_modules/,
                options: {
                    appendTsSuffixTo: [/\.vue$/],
                }
            },
        ]
    },
    plugins: [
        new webpack.ProvidePlugin({
            '_': 'lodash',
            '$': 'jquery',
            'jQuery': 'jquery',
            'window.jQuery': 'jquery', 
        }),
        new LiveReloadPlugin()
    ],
    resolve: {
        extensions: ['.js', '.ts', '.vue', '.jsx', '.tsx', '.vuex'],
        alias: {
            'vue$': 'vue/dist/vue.esm.js',
        }
    }

The problem seem to be in Webpack and/or the babel-loader doesn't take the fabric namepace into account.

So the question is if there is any method to tell Webpack to handle this import in a way that it directly references fabric (or an imported library of that kind) or to import it into Typescript in a way that also Webpack is happy?

like image 666
colonelz Avatar asked Sep 04 '17 08:09

colonelz


People also ask

What is fabric JS?

It is a Javascript lib that takes a normal HTML canvas and gives it some advanced functionalities. By default, Fabric.js supports object-based drawing among other fancy features like animations, scaling, and transforming. Just look at that cute animated ladybug. If that isn’t lit, I don’t know what is.

What is typescript in Webpack?

This guide stems from the Getting Started guide. TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. In this guide we will learn how to integrate TypeScript with webpack.

Where do I put my typescript classes for a drawing canvas?

Here's the libman.json file we used: Note the "destination" settings for the jQuery and FabricJS typings: they are included in the DrawingEditor directory, which is where we will place our TypeScript classes. We can now start building the markup and script for our drawing canvas.

Is there a fabricjs canvas for Razor pages?

We did it! We created a brand new FabricJS canvas onto our Razor Pages app! But it doesn't actually do anything yet, and in the next part of this series, we'll add some very basic line-drawing functionality to our new canvas.


1 Answers

This worked for me:

import 'fabric' ;
declare let fabric: any;

var c = new fabric.Canvas('myCanvas') ;

I'm using @types/fabric 1.5.26 on TypeScript 2.5.3 and webpack 3.5.1

like image 64
semiadam Avatar answered Sep 22 '22 15:09

semiadam