awesome-webextension / webpack-target-webextension

WebExtension Target for Webpack 5. Supports code-splitting and HMR.
MIT License
44 stars 5 forks source link

Support HMR #4

Closed Jack-Works closed 3 years ago

Jack-Works commented 3 years ago

close #3

Please try it with this config:

webpack.config.ts

import { resolve } from 'path'
import { Configuration } from 'webpack'
import WebExtensionTarget = require('webpack-target-webextension')
export default function (): Configuration {
    return {
        target: WebExtensionTarget(),
        entry: {
            background: resolve(__dirname, 'src/background.js'),
            content: resolve(__dirname, 'src/content.js'),
            options: resolve(__dirname, 'src/options.js'),
        },
        mode: 'development',
        optimization: {
            // Chrome bug https://bugs.chromium.org/p/chromium/issues/detail?id=1108199
            splitChunks: { automaticNameDelimiter: '-' },
        },
        output: {
            path: resolve(__dirname, 'js/'),
            publicPath: 'js/',
        },
        devServer: {
            // Have to write disk cause plugin cannot be loaded over network
            writeToDisk: true,
            compress: false,
            hot: true,
            hotOnly: true,
            // WDS does not support chrome-extension:// browser-extension://
            disableHostCheck: true,
            injectClient: true,
            injectHot: true,
            headers: {
                // We're doing CORS request for HMR
                'Access-Control-Allow-Origin': '*',
            },
            // If the content script runs in https, webpack will connect https://localhost:HMR_PORT
            https: true,
        },
    }
}

package.json

{
"dependencies": {
"@types/webpack": "^4.41.22",
"@types/webpack-dev-server": "^3.11.0",
"serve": "^11.3.2",
"ts-node": "^9.0.0",
"typescript": "^4.0.3",
"webpack": "^4.44.2",
"webpack-dev-server": "^3.11.0",
"webpack-target-webextension": "^0.1.3"
},
"scripts": {
"start": "webpack-dev-server --mode development"
}
}

options.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
</head>
<body>
<script src="js/options.js"></script>
</body>
</html>

background.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
</head>
<body>
<script src="js/background.js"></script>
</body>
</html>

manifest.json

{
"name": "Webpack Web Extension HMR",
"version": "1.0.0",
"manifest_version": 2,
"permissions": ["<all_urls>"],
"background": { "page": "background.html" },
"options_ui": { "page": "options.html", "open_in_tab": true },
"web_accessible_resources": ["*.js", "*.json"],
"content_security_policy": "script-src 'self' blob: filesystem: 'unsafe-eval';",
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["js/content.js"]
}
]
}

src/background.js


import { log } from './shared'

console.log(log()) if (module.hot) { module.hot.accept('./shared', (nextMod) => { console.log(log()) }) }


> src/content.js
```js
import { log } from './shared'

console.log(log())

module.hot.accept('./shared', () => {
    console.log(log())
})

src/options.js


import { log } from './shared'

const ele = document.createElement('h1') document.body.appendChild(ele) ele.innerText = log()

module.hot.accept('./shared', () => { ele.innerText = log() })


> src/shared.js
```js
export function log() {
    return 'version 0'
}

Then run npm run start and change src/shared.js to see how HMR works.

Jack-Works commented 3 years ago

@crimx hi did you try this?

crimx commented 3 years ago

Hi sorry for the delay. I'll take the time to test it later today.

crimx commented 3 years ago

I've integrated the hmr example into the project. Please pull and take a look.

Jack-Works commented 3 years ago

Does it work well? If so, I'm happy with that

crimx commented 3 years ago

It works well. Thanks for the PR.

crimx commented 3 years ago

Published.

Jack-Works commented 3 years ago

I have another question. Now we require users to manually change their webpack config, is it possible to modify the config in the plugin?

crimx commented 3 years ago

I think this belongs to another layer. In webpack source the default config is modified somewhere else base on the target name.