bugsnag / webpack-bugsnag-plugins

Webpack plugins for common BugSnag actions.
MIT License
32 stars 29 forks source link

Integration into Laravel Vue Application with Laravel Mix #69

Closed jasperf closed 2 years ago

jasperf commented 3 years ago

Been reading on adding / uploading source maps for easier debugging JavaScript/Vue. That besides PHP debugging . So found your documentation on using the webpack plugin https://docs.bugsnag.com/build-integrations/webpack/ .

Not clear however on the integration into webpack.mix.js . Miss that at https://github.com/bugsnag/webpack-bugsnag-plugins and in documentation https://docs.bugsnag.com/platforms/php/laravel/ .

If we use this in webpack.mix.js:

const mix = require('laravel-mix')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const { BugsnagBuildReporterPlugin } = require('webpack-bugsnag-plugins')
…
if (mix.inProduction()) {
  mix.webpackConfig({
    plugins: [
      new CleanWebpackPlugin({
        cleanStaleWebpackAssets: false,
        protectWebpackAssets: true,
        cleanOnceBeforeBuildPatterns: ['js/components/*'],
      }),
      new BugsnagBuildReporterPlugin({
        apiKey: 'api-key-here',
        publicPath: 'https://site.com/public',
        overwrite: true,
    }),

    ],

    output: {
      chunkFilename: 'js/components/[name].js?id=[contenthash]',
    },
  })
} else {
  mix.webpackConfig({
    output: {
      chunkFilename: 'js/components/[name].js',
    },
  });
}

mix.options({
    processCssUrls: false
});

mix.sass('resources/sass/editor.scss', 'public/css')
    .sass('resources/sass/login.scss', 'public/css')
    .sass('resources/sass/preview.scss', 'public/css')
    .sass('resources/sass/published.scss', 'public/css')
    .sass('resources/sass/dashboard.scss', 'public/css')
    .js('resources/js/editor.js', 'public/js')
    .js('resources/js/preview.js', 'public/js')
    .js('resources/js/published-vendor.js', 'public/js')
    .js('resources/js/published-utils.js', 'public/js')
    .js('resources/js/published.js', 'public/js')
    .js('resources/js/dashboard.js', 'public/js')
    .vue()

if (mix.inProduction()) {
    mix.version();
}
....
  1. What should normally be the publicPath here? Should it be https://site.com/public ? Or do I need to add a slash?
  2. What if staging and production both use inProduction, but different domains(staging.domain.com and domain.com)?
  3. Any recommended Laravel Mix template available?

NB Reading https://github.com/bugsnag/webpack-bugsnag-plugins/issues/11 some now as well, but not quite clear yet and would appreciate some feedback.

jasperf commented 3 years ago

Testing

...
if (mix.inProduction()) {
  mix.webpackConfig({
    devtool: 'source-map', 
    plugins: [
      new CleanWebpackPlugin({
        cleanStaleWebpackAssets: false,
        protectWebpackAssets: true,
        cleanOnceBeforeBuildPatterns: ['js/components/*'],
      }),
      new BugsnagSourceMapUploaderPlugin({
        apiKey: process.env.BUGSNAG_API_KEY,
        appVersion: process.env.BUGSNAG_APP_VERSION,
        publicPath: '*/js'
...

now

yousif-bugsnag commented 3 years ago

Hi @jasperf,

  1. publicPath should be the path to your bundled assets as it appears in the stacktrace. If your app is running in the browser this is normally the base URL of your app, e.g. https://site.com/public/. This should have a trailing slash, but the plugin will add one if not present so it's not required.
  2. You can use wildcards for the publicPath if your JS is being served at multiple URLs, e.g. https://*.site.com/public/
  3. We don't have an example laravel mix template, but it shouldn't require any extra configuration beyond the standard webpack examples
jasperf commented 3 years ago

@yousif-bugsnag Thanks for getting back on this. As I posted we are now using a wildcard as part of publicPath and we did see feedback in terminal on running npm run prod . Feedback that source maps were being uploaded.

Only we do not have new errors yet in which the source maps are loaded. Old errors still show that source maps do not load. Is there a way to check uploaded sourcemaps besides their usage in error reports?

jasperf commented 3 years ago

Also it seems now that this setup I shared

...
if (mix.inProduction()) {
  mix.webpackConfig({
    devtool: 'source-map', 
    plugins: [
      new CleanWebpackPlugin({
        cleanStaleWebpackAssets: false,
        protectWebpackAssets: true,
        cleanOnceBeforeBuildPatterns: ['js/components/*'],
      }),
      new BugsnagSourceMapUploaderPlugin({
        apiKey: process.env.BUGSNAG_API_KEY,
        appVersion: process.env.BUGSNAG_APP_VERSION,
        publicPath: '*/js'
      })
    ],

    output: {
      chunkFilename: 'js/components/[name].js?id=[contenthash]',
    },
  })
} else {
  mix.webpackConfig({
    output: {
      chunkFilename: 'js/components/[name].js',
    },
  });
}
...

is causing production request for source maps also which are not on the server.. and should not be. Any ideas how we can avoid that @yousif-bugsnag? Perhaps I should have a separate block?

jasperf commented 3 years ago

We will by doing things with hidden-source-map https://webpack.js.org/configuration/devtool/#production

jasperf commented 3 years ago

Using hidden-source-map got me errors

<i> [BugsnagSourceMapUploaderPlugin] uploading sourcemap for "*/js/js/components/editor/smt-i.js?id=6bf8cf2a14c0ec3b"
<i> [BugsnagSourceMapUploaderPlugin] uploading sourcemap for "*/js/js/components/editor/smt-contact-module.js?id=a24b946c0ba7fdca"
<i> [BugsnagSourceMapUploaderPlugin] uploading sourcemap for "*/js/main.js"
<i> [BugsnagSourceMapUploaderPlugin] uploading sourcemap for "*/js/js/components/editor/smt-image-module.js?id=5bc33caddd1bcfe2"
....
<i> [BugsnagSourceMapUploaderPlugin] uploading sourcemap for "*/js/js/components/publish/smt-diagonal-line-module.js?id=9c2a74b58dd93f85"
[webpack-cli] NetworkError: HTTP status 409 received from upload API
    at /Users/jasper/code/site.com/site.com/node_modules/@bugsnag/source-maps/dist/Request.js:105:33
    at ConcatStream.<anonymous> (/Users/jasper/code/site.com/site.com/node_modules/concat-stream/index.js:37:43)
    at ConcatStream.emit (node:events:402:35)
    at finishMaybe (/Users/jasper/code/site.com/site.com/node_modules/readable-stream/lib/_stream_writable.js:624:14)
    at afterWrite (/Users/jasper/code/site.com/site.com/node_modules/readable-stream/lib/_stream_writable.js:470:3)
    at processTicksAndRejections (node:internal/process/task_queues:85:21) {
  isRetryable: false,
  code: 1,
  cause: null,
  responseText: 'duplicate source map file for */js/main.js version 1.11.8'
jasperf commented 3 years ago

Never mind, I needed a new version.

jasperf commented 2 years ago

I just had another error but was told no sourcemap was located, but they were uploaded. How to debug this?

Generate source maps to see the original source file and line numbers. No link to a source map was found in your minified JavaScript file. Either include the link when generating source maps or upload them to us. (Note that events are not reprocessed after source maps are uploaded.)

Here is what we are using:

if (mix.inProduction()) {
  mix.webpackConfig({
    devtool: 'hidden-source-map', 
    plugins: [
      new CleanWebpackPlugin({
        cleanStaleWebpackAssets: false,
        protectWebpackAssets: true,
        cleanOnceBeforeBuildPatterns: ['js/components/*'],
      }),
      new BugsnagSourceMapUploaderPlugin({
        apiKey: process.env.BUGSNAG_API_KEY,
        appVersion: process.env.BUGSNAG_APP_VERSION,
        publicPath: '*/js'
      })
    ],

    output: {
      chunkFilename: 'js/components/[name].js?id=[contenthash]',
    },
  })
} else {
  mix.webpackConfig({
    output: {
      chunkFilename: 'js/components/[name].js',
    },
  });

We chose hidden-source-map to have the source maps only uploaded and not shown to end users. But we still need Bugsnag to be able to read the sourcemaps. How do we do this?

NB we we had source-map only we had 404s as well so perhaps we need to do something still to refer to sourcemaps?

Also possibly related https://github.com/laravel-mix/laravel-mix/issues/1651 and https://github.com/laravel-mix/laravel-mix/issues/1793

xljones commented 2 years ago

@jasperf By default, we look for uploaded-to-Bugsnag maps first, then if no matches are found there, we look for a //# sourceMappingURL (or X-SourceMap header). The error message you've quoted above suggests that:

  1. No uploaded-to-Bugsnag source map was found that matches a minified frame in this stacktrace, the app version, or both.
  2. No //# sourceMappingURL exists on this webpage, which figures as you're using hidden-source-map which removes this comment from your output bundle.

If you could drop us a link to an event that's failing to map but that you would expect it to map, we can take a look into that specific example and help explain why. You can message us at support@bugsnag.com or drop the link here.

We chose hidden-source-map to have the source maps only uploaded and not shown to end users. But we still need Bugsnag to be able to read the sourcemaps. How do we do this?

You would need to upload the sourcemaps to Bugsnag, which it looks like you're already doing according the Webpack snippet.

jasperf commented 2 years ago

Will email de link to the even to you @xander-jones . Hope we can work out what is missing. Setup was kind of tricky for us and we really want to make it work so debugging becomes easier then it is without source maps.

update

email sent but link here once more https://app.bugsnag.com/smart48/smart48/errors/61a0b97d9abbc10007c35b6e?filters[event.since]=7d&filters[app.release_stage]=production&sort=events

yousif-bugsnag commented 2 years ago

Thanks for the link @jasperf! I'm going to close this issue as we are communicating via the support ticket, but for the benefit of future travellers:

Bugsnag uses both the frame URL and the app version to match uploaded source maps to events, so if you are specifying an appVersion in your webpack config you will need to ensure the same value is used for the appVersion config value when initialising Bugsnag in your JS app.

jasperf commented 2 years ago

Also good to mention this which was mentioned by Bugsnag in email

So to summarize, you should:

- Specify an appVersion when initializing Bugsnag in your app - Set the publicPath to '*' in your webpack config as js was mentioned twice in path

jasperf commented 2 years ago

Had to leave this be for a while but I am afraid I am still seeing


Missing JavaScript files:Provide JavaScript files for improved grouping and better stack traces
Ensure uploaded source maps match this version or make your JavaScript files accessible from our servers. (Note that events are not reprocessed after source maps are uploaded.)
--
[Ensure uploaded source maps match this version or make your JavaScript files accessible from our servers. (Note that events are not reprocessed after source maps are uploaded.)]()
--

and we do use

if (mix.inProduction()) {
  mix.webpackConfig({
    devtool: 'hidden-source-map', 
    plugins: [
      new CleanWebpackPlugin({
        cleanStaleWebpackAssets: false,
        protectWebpackAssets: true,
        cleanOnceBeforeBuildPatterns: ['js/components/*'],
      }),
      new BugsnagSourceMapUploaderPlugin({
        apiKey: process.env.BUGSNAG_API_KEY,
        appVersion: process.env.BUGSNAG_APP_VERSION,
        publicPath: '*'
      })
    ],

and we update BUGSNAG_APP_VERSION=1.15.13 in .env everynpm run prod` . And the files are uploaded.

yousif-bugsnag commented 2 years ago

Hey @jasperf at a glance it looks like source maps are being applied correctly to recent events in your project - is this still an issue you're experiencing? If please share a link again with support@bugsnag.com and we can take a look.

jasperf commented 2 years ago

I have zero JS error events currently. Guess we are deploying well to production. But before that I never had sourcemaps loading properly for JS. Will be testing some more with staging added as environment.

jasperf commented 2 years ago

@yousif-bugsnag Saw the latest files built getting uploaded on npm run prod but still I see:

TypeError/editor
u.left.replace is not a function
12 minutes ago
Apr 7th, 12:11:08 GMT+7
production
unhandled

Missing JavaScript files: Provide JavaScript files for improved grouping and better stack traces View Details Source maps guide

TypeError · u.left.replace is not a function
https://site.test/js/editor.js:2:141391 n.value 
https://site.test/js/components/editor/module.js:1:20167 a.positionObject   
https://site.test/js/editor.js:2:1889012 hn.get 
https://site.test/js/editor.js:2:1890152 hn.evaluate    
https://site.test/js/editor.js:2:1890917 a.positionObject   
https://site.test/js/components/editor/module.js:1:23890 a.<anonymous>  
https://site.test/js/editor.js:2:1896989 a.t._render    
https://site.test/js/editor.js:2:1930681 a.r    
https://site.test/js/editor.js:2:1889012 hn.get 
https://site.test/js/editor.js:2:1888930 new hn
luke-belton commented 2 years ago

Hi @jasperf - I've had a look at your dashboard and it appears that your events are missing an app version, whereas your sourcemaps have an app version set. The app versions must match in order for source maps to be applied correctly. You can read about setting app version in our docs.

If you're still having trouble please feel free to write back into support@bugsnag.com.

jasperf commented 2 years ago

@luke-belton our Laravel Vue app has the app version set in .env using BUGSNAG_APP_VERSION=1.19 which is loaded from webpack.mix.js:

const mix = require('laravel-mix')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const { BugsnagSourceMapUploaderPlugin } = require('webpack-bugsnag-plugins')
....
if (mix.inProduction()) {
  mix.webpackConfig({
    devtool: 'hidden-source-map', 
    plugins: [
      new CleanWebpackPlugin({
        cleanStaleWebpackAssets: false,
        protectWebpackAssets: true,
        cleanOnceBeforeBuildPatterns: ['js/components/*'],
      }),
      new BugsnagSourceMapUploaderPlugin({
        apiKey: process.env.BUGSNAG_API_KEY,
        appVersion: process.env.BUGSNAG_APP_VERSION,
        publicPath: '*'
      })
    ],

    output: {
      chunkFilename: 'js/components/[name].js?id=[contenthash]',
    },
  })
} else {
  mix.webpackConfig({
    output: {
      chunkFilename: 'js/components/[name].js',
    },
  });
}
....

And in main js files for app we use

....
import bugsnag from '@bugsnag/js'
import bugsnagVue from '@bugsnag/plugin-vue'

if (process.env.NODE_ENV == 'production' || process.env.NODE_ENV == 'staging') {
    let bugsnagClient = bugsnag({
        apiKey: 'key',
        interactionBreadcrumbsEnabled: false
    })
    bugsnagClient.use(bugsnagVue, Vue)
}
...

So what else are we missing here?

yousif-bugsnag commented 2 years ago

Hi @jasperf,

Setting the appVersion in the webpack plugin means that your source maps will be uploaded with an appVersion set, but this is separate to the Bugsnag client. In order for events to be sent with an appVersion (which is necessary for matching with uploaded source maps) you will also need to set the appVersion config option when initialising Bugsnag in main.js.

You should also be calling Bugsnag.start() passing in the Vue plugin to initialise the client - please see our Vue integration guide for how to initialise Bugsnag in your Vue app: https://docs.bugsnag.com/platforms/javascript/vue/

import Bugsnag from '@bugsnag/js'
import BugsnagPluginVue from '@bugsnag/plugin-vue'

if (process.env.NODE_ENV == 'production' || process.env.NODE_ENV == 'staging') {
    Bugsnag.start({
      apiKey: 'YOUR_API_KEY',
      appVersion: process.env.BUGSNAG_APP_VERSION
      plugins: [new BugsnagPluginVue()]
    })
}
jasperf commented 2 years ago

@yousif-bugsnag Thanks a lot for explaining this in more detail. Seems I was missing Bugsnag.start() to initialize the client. this to allow the appVersion to be sent alone with events, not just in the uploaded source maps.

We now have

import Bugsnag from '@bugsnag/js'
import BugsnagVue from '@bugsnag/plugin-vue'

if (process.env.NODE_ENV == 'production' || process.env.NODE_ENV == 'staging') {
  Bugsnag.start({
    apiKey: 'key',
    appVersion: process.env.BUGSNAG_APP_VERSION,
    plugins: [new BugsnagPluginVue()]
  })
}

BugsnagVue is not being used here in this setup. So perhaps you meant plugins: [new BugsnagVue()]instead of BugsnagPluginVue()?

also wonder if we should use

const bugsnagVue = Bugsnag.getPlugin('vue')
bugsnagVue.installVueErrorHandler(Vue)
luke-belton commented 2 years ago

Hi @jasperf - apologies, the import statement above should have been:

import BugsnagPluginVue from '@bugsnag/plugin-vue'

I've edited our last comment to reflect that.

Are you using Vue 2 or Vue 3? The way you install the error handler will depend on which version of Vue you are using, as described in our docs: https://docs.bugsnag.com/platforms/javascript/vue/#basic-configuration.

jasperf commented 2 years ago

@luke-belton Thanks for the edit. We are using Vue 2 so that would mean

const bugsnagVue = Bugsnag.getPlugin('vue')
bugsnagVue.installVueErrorHandler(Vue)

Should this be added before or after imports at

import Bugsnag from '@bugsnag/js'
import BugsnagPluginVue from '@bugsnag/plugin-vue'

if (process.env.NODE_ENV == 'production' || process.env.NODE_ENV == 'staging') {
  Bugsnag.start({
    apiKey: 'key',
    appVersion: process.env.BUGSNAG_APP_VERSION,
    plugins: [new BugsnagPluginVue()]
  })
}

?

jasperf commented 2 years ago

Version

import Bugsnag from '@bugsnag/js'
import BugsnagPluginVue from '@bugsnag/plugin-vue'

if (process.env.NODE_ENV == 'production' || process.env.NODE_ENV == 'staging') {
    const bugsnagClient = Bugsnag.start({
    apiKey: 'key',
    appVersion: process.env.BUGSNAG_APP_VERSION,
    plugins: [new BugsnagPluginVue()]
  })

  Vue.use(bugsnagClient) // // this is also important
}

did cause errors on build mentioning BugsnagPluginVue() is not a constructor . If I am still missing something please let me know.

yousif-bugsnag commented 2 years ago

Hi @jasperf,

@luke-belton Thanks for the edit. We are using Vue 2 so that would mean

const bugsnagVue = Bugsnag.getPlugin('vue')
bugsnagVue.installVueErrorHandler(Vue)

This is the correct way to initialise Bugsnag in Vue 2. Note that this should be added after the call to Bugsnag.start()

jasperf commented 2 years ago

@yousif-bugsnag thanks for getting back to me. Previously added code with different Vue.use call still had the error that BugsnagPluginVue() was not a constructor.

When we tested:

import Bugsnag from '@bugsnag/js'
import BugsnagPluginVue from '@bugsnag/plugin-vue'

if (process.env.NODE_ENV == 'production' || process.env.NODE_ENV == 'staging') {
  Bugsnag.start({
    apiKey: 'key',
    appVersion: process.env.BUGSNAG_APP_VERSION,
    plugins: [new BugsnagPluginVue()]
  })

const bugsnagVue = Bugsnag.getPlugin('vue')
bugsnagVue.installVueErrorHandler(Vue)

}

in app.js (not webpack.mix.js) we still have the same error Uncaught TypeError: BugsnagPluginVue(...) is not a constructor or locally built Uncaught TypeError: _bugsnag_plugin_vue__WEBPACK_IMPORTED_MODULE_46___default(...) is not a constructor

Added

{
"compilerOptions": {
    "baseUrl": ".",
    "module": "CommonJS",
    "resolveJsonModule": true,
    "strictNullChecks": true,
    "esModuleInterop": true,
...

with "esModuleInterop": true, to jsconfig.json but it did not help either

Perhaps something off with the import here. But if I use require instead I still get Uncaught TypeError: BugsnagPluginVue is not a constructor. Import with {} does not solve the issue either so something else must be the problem.

fyi

npm view @bugsnag/js      
@bugsnag/js@7.16.2 | MIT | deps: 2 | versions: 109
Universal Javascript error reporting. Automatically detect JavaScript errors in the browser and Node.js, with plugins for React, Vue, Angular, Express, Restify and Koa.
https://www.bugsnag.com/
...
npm view @bugsnag/plugin-vue
@bugsnag/plugin-vue@7.16.2 | MIT | deps: none | versions: 84
Vue.js integration for bugsnag-js
https://www.bugsnag.com/
....
ghost commented 2 years ago

@jasperf Please update to the latest version (7.16.*) for @bugsnag/js and @bugsnag/plugin-vue, everything will work fine.

jasperf commented 2 years ago

Built locally now with latest versions but did get

bugsnag] installVueErrorHandler() was called unnecessarily
installVueErrorHandler @ file.js?id=cb0bf50710bd2e81dc36:2

so made it

import Bugsnag from '@bugsnag/js'
import BugsnagPluginVue from '@bugsnag/plugin-vue'

if (process.env.NODE_ENV == 'production' || process.env.NODE_ENV == 'staging') {
  Bugsnag.start({
    apiKey: 'key',
    appVersion: process.env.BUGSNAG_APP_VERSION,
    plugins: [new BugsnagPluginVue()]
  })

// call not needed
// const bugsnagVue = Bugsnag.getPlugin('vue')
// bugsnagVue.installVueErrorHandler(Vue)

}
jasperf commented 2 years ago

Unfortunately I am still getting

Source mapping failed:Missing source map linkHide DetailsSource maps guideGenerate source maps to see the original source file and line numbers. No link to a source map was found in your minified JavaScript file. Either include the link when generating source maps or upload them to us. (Note that events are not reprocessed after source maps are uploaded.)
--
Missing source map link
Hide Details
[Source maps guide](https://docs.bugsnag.com/platforms/browsers/js/source-maps/)
Generate source maps to see the original source file and line numbers. No link to a source map was found in your minified JavaScript file. Either include the link when generating source maps or upload them to us. (Note that events are not reprocessed after source maps are uploaded.)

On npm run prod we do generate sourcemaps and these are uploaded.

We do use devtool: 'hidden-source-map' Do we need to include source maps links in our production code to have this work @yousif-bugsnag ?

we now have

...
if (mix.inProduction()) {
  mix.webpackConfig({
    devtool: 'hidden-source-map', 
    plugins: [
      new CleanWebpackPlugin({
        cleanStaleWebpackAssets: false,
        protectWebpackAssets: true,
        cleanOnceBeforeBuildPatterns: ['js/components/*'],
      }),
      new BugsnagSourceMapUploaderPlugin({
        apiKey: process.env.BUGSNAG_API_KEY,
        appVersion: process.env.BUGSNAG_APP_VERSION,
        publicPath: '*'
      })
    ],
...

should it be

...
if (mix.inProduction()) {
  mix.webpackConfig({
    devtool: 'source-map', 
    plugins: [
      new CleanWebpackPlugin({
        cleanStaleWebpackAssets: false,
        protectWebpackAssets: true,
        cleanOnceBeforeBuildPatterns: ['js/components/*'],
      }),
    ],
...

Or...?

luke-belton commented 2 years ago

Hi @jasperf - you should be able to use the hidden-source-map devtool option if you're uploading source maps to Bugsnag. We have guidance on uploading source maps in our docs: https://docs.bugsnag.com/platforms/javascript/source-maps/#uploading-source-maps-recommended.

If you're still having trouble, please can you write into support@bugsnag.com referencing this GitHub issue and sharing links to events in your dashboard that aren't being mapped, as well as the command you're using to upload source maps. Thanks!

jasperf commented 2 years ago

@luke-belton we tested

appVersion: `'${process.env.BUGSNAG_APP_VERSION}'`,

in

if (process.env.NODE_ENV == 'production' || process.env.NODE_ENV == 'staging') {
  Bugsnag.start({
    apiKey: 'redacted',
    appVersion: `'${process.env.BUGSNAG_APP_VERSION}'`,
    plugins: [new BugsnagPluginVue()]
  })

// call installVueErrorHandler not needed  
// const bugsnagVue = Bugsnag.getPlugin('vue')
// bugsnagVue.installVueErrorHandler(Vue)

}

to have appVersion uploaded as a string as well. Seems it was rejected by Bugsnag because it was not sent in as a string like the API key.

However, it does not work yet

Mi().start({
    apiKey: "key",
    appVersion: "'".concat(Fi.env.BUGSNAG_APP_VERSION, "'"),
    plugins: [new (Bi())]
}),
jasperf commented 2 years ago

Seems process.env does not work. Not inside Bugsnag.start nor defined as const before the if statement. Hardcoded version as string for now. But not happy about it.

djskinner commented 2 years ago

Are you using https://webpack.js.org/plugins/define-plugin/? If you want process.env.x to be available in the bundle at runtime you need to "export" it by using DefinePlugin

jasperf commented 2 years ago

@djskinner Thanks for the tip. We do use Webpack/Laravel Mix with some plugins already. No we are not using Define Plugin yet. Looks like something we should use. The code loading the appVersion is in two .js files now and hard coded.

But I guess if we add:

new webpack.DefinePlugin({
  'process.env.BUGSNAG_APP_VERSION': JSON.stringify(process.env.BUGSNAG_APP_VERSION),
});

and perhaps api key too inside webpack.mix.js.:

if (mix.inProduction()) {
  mix.webpackConfig({
    devtool: 'hidden-source-map', 
    plugins: [
      new DefinePlugin({
       'process.env.BUGSNAG_APP_VERSION': JSON.stringify(process.env.BUGSNAG_APP_VERSION),
       'process.env.BUGSNAG_API_KEY': JSON.stringify(process.env.BUGSNAG_API_KEY),
      }),
      new CleanWebpackPlugin({
        cleanStaleWebpackAssets: false,
        protectWebpackAssets: true,
        cleanOnceBeforeBuildPatterns: ['js/components/*'],
      }),
      new BugsnagSourceMapUploaderPlugin({
        apiKey: process.env.BUGSNAG_API_KEY,
        appVersion: process.env.BUGSNAG_APP_VERSION,
        publicPath: '*'
      })
    ],

    output: {
      chunkFilename: 'js/components/[name].js?id=[contenthash]',
    },
  })
} else {
  mix.webpackConfig({
    output: {
      chunkFilename: 'js/components/[name].js',
    },
  });
}

The values should be available at runtime. Perhaps not for usage in the webpack file, but for inside the editor.js and preview.js. Perhaps I should then also remove

BugsnagSourceMapUploaderPlugin
djskinner commented 2 years ago

I think you should keep BugsnagSourceMapUploaderPlugin so that your source maps get uploaded for production builds

jasperf commented 2 years ago

@djskinner True. Need to keep it for uploading with path. Thank you for your feedback. Much appreciated. Will test all out soon. Hope it will all work once and for all.

jasperf commented 2 years ago

In the end I realized Laravel Mix does have its own implementation of Define Plugin. But it blocks loading in .env values unless you prefix them with MIX_ like MIX_BUGSNAG_APP_VERSION=. Version loading now. Checked source code on staging. Just need to test on Bugsnag side.