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

Support dynamic import() from ES6 module #180

Open
BeeDice opened this issue Sep 29, 2023 · 2 comments
Open

Support dynamic import() from ES6 module #180

BeeDice opened this issue Sep 29, 2023 · 2 comments

Comments

@BeeDice
Copy link

BeeDice commented Sep 29, 2023

To reproduce:

<head>
    <script type="module">
        import('https://cdnjs.cloudflare.com/ajax/libs/jsmediatags/3.9.5/jsmediatags.min.js');
    </script>
</head>

Error:

Uncaught TypeError: Cannot use 'in' operator to search for 'Object' in undefined
    at $jscomp.polyfill (jsmediatags.min.js:2:113)
    at jsmediatags.min.js:2:257

Reason is that this is undefined in ES6 modules:

$jscomp.global = $jscomp.getGlobal(this);  // === undefined

I understand we use this here to support Node. Can getGlobal() return window if it is passed undefined?

@Cattn
Copy link

Cattn commented Jul 6, 2024

This.

@SunboX
Copy link

SunboX commented Oct 29, 2024

I did it like this:

I created a new "project" with a package.json file:

{
    "name": "YOU_NAME_IT",
    "version": "3.9.7",
    "scripts": {
        "build": "npx webpack"
    },
    "devDependencies": {
        "jsmediatags": "^3.9.7",
        "@babel/core": "^7.26.0",
        "@babel/preset-env": "^7.26.0",
        "babel-loader": "^9.2.1",
        "webpack": "^5.95.0",
        "webpack-cli": "^5.1.4"
    }
}

Than I created a webpack.config.js file like this:

module.exports = {
    mode: 'production',
    entry: './src/index.js',
    output: {
        filename: 'jsmediatags.mjs',
        path: __dirname + '/dist',
        libraryTarget: 'module'
    },
    experiments: {
        outputModule: true
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/
            }
        ]
    }
}

and a .babelrc file like this:

{
    "presets": ["@babel/preset-env"]
}

I also create a folder src containing one file index.js like this:

const jsmediatags = require('../node_modules/jsmediatags/dist/jsmediatags.min.js')
export default jsmediatags

export class MediaTagReader {
    static read(file, options) {
        return new Promise((resolve, reject) => {
            new jsmediatags.Reader(file).read({
                onSuccess: resolve,
                onError: reject
            })
        })
    }
}

after that, you simply run npm install and npm run build... and you're getting a new file jsmediatags.mjs inside the dist folder.

Usage

import { MediaTagReader } from '/PATH_TO_YOUR_PACKAGE_NAME/dist/jsmediatags.mjs'

try {
    const { tags } = await MediaTagReader.read('http://path_to_your.mp3')

    const picture = tags.picture
    if (picture) {
        const { data, format } = picture
        const byteArray = new Uint8Array(data)
        const blob = new Blob([byteArray], { type: format })
        const url = URL.createObjectURL(blob)

        console.log('Album cover found in this MP3 file:', url)

        URL.revokeObjectURL(url)
    } else {
        console.log('No album cover found in this MP3 file.')
    }
} catch (error) {
    console.error('Error reading tags:', error.type, error.info)
}

Hope that helps someone. :)

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