javascript - Proper way to import and use node modules with Laravel Mix - Stack Overflow

I'm just starting to use Laravel (v 8.x) Mix in a project, and am finding it frustrating to implem

I'm just starting to use Laravel (v 8.x) Mix in a project, and am finding it frustrating to implement Javascript from node modules.

To begin, I have this in my webpack.mix.js:

mix.js('node_modules/mxgraph/javascript/mxClient.min.js', 'public/js');
mix.js('resources/js/*.js', 'public/js').postCss('resources/css/app.css', 'public/css', [
    require('postcss-import'),
    require('tailwindcss'),
    require('autoprefixer'),
]).version();

Next, my app.js contains the following:

import Canvas from './canvas';

require('mxgraph');

const canvas = new Canvas();

...which imports canvas.js:

export default class Canvas {
    constructor() {
        this.container = document.getElementById('graphContainer');
        if (!mxClient.isBrowserSupported())
        {
            // Displays an error message if the browser is not supported.
            alert('Browser is not supported!');
        }
.
.
.
    }
}

...and in the Scripts section of my Blade layout:

<script src="{{ mix('js/mxClient.min.js') }}" defer></script>
<script src="{{ mix('js/app.js') }}" defer></script>

When I load the page, I get the following error in the console:

Uncaught ReferenceError: mxClient is not defined
    at new Canvas (app.js:3866)
    at Module../resources/js/app.js (app.js:3813)
    at __webpack_require__ (app.js:114081)
    at app.js:114143
    at app.js:114149

var mxClient is definitely present in mxClient.min.js, and the reference to it in Canvas occurs after it's loaded.

I've tried a bunch of variations, and nothing seems to work. Any guidance would be greatly appreciated.

I'm just starting to use Laravel (v 8.x) Mix in a project, and am finding it frustrating to implement Javascript from node modules.

To begin, I have this in my webpack.mix.js:

mix.js('node_modules/mxgraph/javascript/mxClient.min.js', 'public/js');
mix.js('resources/js/*.js', 'public/js').postCss('resources/css/app.css', 'public/css', [
    require('postcss-import'),
    require('tailwindcss'),
    require('autoprefixer'),
]).version();

Next, my app.js contains the following:

import Canvas from './canvas';

require('mxgraph');

const canvas = new Canvas();

...which imports canvas.js:

export default class Canvas {
    constructor() {
        this.container = document.getElementById('graphContainer');
        if (!mxClient.isBrowserSupported())
        {
            // Displays an error message if the browser is not supported.
            alert('Browser is not supported!');
        }
.
.
.
    }
}

...and in the Scripts section of my Blade layout:

<script src="{{ mix('js/mxClient.min.js') }}" defer></script>
<script src="{{ mix('js/app.js') }}" defer></script>

When I load the page, I get the following error in the console:

Uncaught ReferenceError: mxClient is not defined
    at new Canvas (app.js:3866)
    at Module../resources/js/app.js (app.js:3813)
    at __webpack_require__ (app.js:114081)
    at app.js:114143
    at app.js:114149

var mxClient is definitely present in mxClient.min.js, and the reference to it in Canvas occurs after it's loaded.

I've tried a bunch of variations, and nothing seems to work. Any guidance would be greatly appreciated.

Share Improve this question edited Mar 25, 2021 at 18:35 miken32 42.8k16 gold badges125 silver badges174 bronze badges asked Jan 24, 2021 at 14:48 mpemburnmpemburn 2,8942 gold badges38 silver badges42 bronze badges 10
  • I am trying to reproduce this. Is the canvas CanvasJs? And mxclient - is that ing from mxGraph or a separate file? – codedge Commented Jan 24, 2021 at 19:36
  • Thanks! The canvas will be created in a Blade file that’s included in the layout. It has a div with the id of graphContainer. Mix pulls in build.js from node_modules/mxgraph and uses this to import mxClient and a bunch of other files. – mpemburn Commented Jan 24, 2021 at 20:31
  • Ok, but I need to know the js libraries. Is that the CnvasJs lib - canvasjs.? – codedge Commented Jan 24, 2021 at 20:36
  • Sorry, I misunderstood. It’s here: npmjs./package/mxgraph (npm install mxgraph) – mpemburn Commented Jan 24, 2021 at 21:44
  • Ok, and why do you import mxClient separately in your webpach.mix.js and additionally mxgraph in your app.js? – codedge Commented Jan 24, 2021 at 21:46
 |  Show 5 more ments

2 Answers 2

Reset to default 1

After a lot more poking and searching around, I found a method that works. It was based on what I found here:

https://www.programmersought./article/85491421858/

My implementation seems a bit clunky, but it does work, and I can now continue the project I'm trying to develop with mxGraph.

Thus, I no longer pull in mxgraph explicitly in webpack.mix.js, so it now reverts to the Laravel default:

mix.js('resources/js/*.js', 'public/js').postCss('resources/css/app.css', 'public/css', [
    require('postcss-import'),
    require('tailwindcss'),
    require('autoprefixer'),
]).version();

I've also removed require('mxgraph'); from app.js, so it just looks like this:

import Canvas from './canvas';

const canvas = new Canvas();

My canvas.js now looks like this:

import mx from 'mxgraph';

const mxgraph = mx({
    mxImageBasePath: './src/images',
    mxBasePath: './src'
});

window.mxGraph = mxgraph.mxGraph;
window.mxGraphModel = mxgraph.mxGraphModel;
window.mxEvent = mxgraph.mxEvent;
window.mxEditor = mxgraph.mxEditor;
window.mxGeometry = mxgraph.mxGeometry;
window.mxRubberband = mxgraph.mxRubberband;
window.mxDefaultKeyHandler = mxgraph.mxDefaultKeyHandler;
window.mxDefaultPopupMenu = mxgraph.mxDefaultPopupMenu;
window.mxStylesheet = mxgraph.mxStylesheet;
window.mxDefaultToolbar = mxgraph.mxDefaultToolbar;

const {mxGraph, mxClient, mxEvent, mxCodec, mxUtils, mxConstants, mxPerimeter, mxRubberband} = mxgraph;

export default class Canvas {
    constructor() {
        let container = document.getElementById('graphContainer');
        if (typeof(mxClient) !== 'undefined') {
            this.draw(container);
        }
    }

    draw (container) {
        if (! mxClient.isBrowserSupported())
        {
            // Displays an error message if the browser is not supported.
            mxUtils.error('Browser is not supported!', 200, false);
        }
        else
        {
            // Disables the built-in context menu
            mxEvent.disableContextMenu(container);

            // Creates the graph inside the given container
            var graph = new mxGraph(container);

            // Enables rubberband selection
            new mxRubberband(graph);

            // Gets the default parent for inserting new cells. This
            // is normally the first child of the root (ie. layer 0).
            var parent = graph.getDefaultParent();

            // Adds cells to the model in a single step
            graph.getModel().beginUpdate();
            try
            {
                var v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30);
                var v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30);
                var e1 = graph.insertEdge(parent, null, '', v1, v2);
              
            }
            finally
            {
                // Updates the display
                graph.getModel().endUpdate();
            }
        }
    }
}

Most of the code in the draw() method is taken from an mxGraph "Hello World" demo (https://jgraph.github.io/mxgraph/docs/manual.html).

Many thanks to @codedge for the time you spent helping me!

So, after playing around I found what you can do.

Assemble one file

Put mxClient.min.js and app.js into one file by doing

mix.js(
    [
        "resources/js/app.js",
        "node_modules/mxgraph/javascript/mxClient.min.js",
    ],
    "public/js"
).postCss('resources/css/app.css', 'public/css', [
    require('postcss-import'),
    require('tailwindcss'),
    require('autoprefixer'),
]).version();

Import mxGraph and Canvas

In your app.js you can put that

import "./canvas";

require("mxgraph");

const canvas = new Canvas();

and npm run dev runs without issues.

Update

I found a (maybe easier) option. Don't include mxClient in your webpack.mix.js, only your app.js is needed.

// app.js

window.mxClient = new require("mxgraph")().mxClient;

let isBrowserSupported = mxClient.isBrowserSupported();

console.log(isBrowserSupported);

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745417944a4626835.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信