最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Fabric.js with Typescript and Webpack: Canvas is not a constructor - Stack Overflow

programmeradmin3浏览0评论

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/ponents')
                ],
                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?

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/ponents')
                ],
                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?

Share Improve this question asked Sep 4, 2017 at 8:14 colonelzcolonelz 811 silver badge4 bronze badges 5
  • what about import { fabric } from 'fabric' ? – AndreaBogazzi Commented Sep 4, 2017 at 22:39
  • Yes, i tried that but that results only in an error: error TS2305: Module '".../node_modules/@types/fabric/index"' has no exported member 'fabric'. – colonelz Commented Sep 7, 2017 at 10:59
  • Where did you take the type definition for fabricjs? – AndreaBogazzi Commented Sep 7, 2017 at 11:09
  • I used the one from @types/fabric installed them via npm and left them in the folder under node_modules/@types/fabric. – colonelz Commented Sep 7, 2017 at 21:58
  • I have the exact same issue, Im using it along with a react app which has been setup using create-react-app. Any idea on how to solve the same without modifying webpack. – Viswas Menon Commented Mar 14, 2018 at 18:58
Add a ment  | 

2 Answers 2

Reset to default 3

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

The solution lied in the configuration of webpack.mix.js. The exports-loader has to be added for fabric to solve the problem. The follwoing rule were added:

            rules: [
            ...
            {
                test: /fabric(\.min)?\.js$/,
                use: 'exports-loader?fabric',
            },
        ]

and fabric can be used like in variant a:

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

Make sure the exports-loader is installed. I found the hint here: https://github./OfficeDev/office-ui-fabric-js/issues/258

发布评论

评论列表(0)

  1. 暂无评论