Skip to content

Commit

Permalink
fix: adjust webpack rspack hooks sequence (#326)
Browse files Browse the repository at this point in the history
Co-authored-by: fengmingjian <[email protected]>
  • Loading branch information
qiYuei and fengmingjian authored Sep 17, 2023
1 parent f6dff68 commit 63e027a
Show file tree
Hide file tree
Showing 11 changed files with 183 additions and 28 deletions.
14 changes: 7 additions & 7 deletions src/rspack/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,26 +32,26 @@ export function getRspackPlugin<UserOptions = Record<string, never>>(
}
const rawPlugins = toArray(factory(userOptions!, meta))
for (const plugin of rawPlugins) {
// transform hook
if (plugin.transform) {
// load hook
if (plugin.load) {
const use: RuleSetUseItem = {
loader: TRANSFORM_LOADER,
loader: LOAD_LOADER,
options: { plugin },
}

compiler.options.module.rules.unshift({
enforce: plugin.enforce,
include: /.*/,
use,
})
}

// load hook
if (plugin.load) {
// transform hook
if (plugin.transform) {
const use: RuleSetUseItem = {
loader: LOAD_LOADER,
loader: TRANSFORM_LOADER,
options: { plugin },
}

compiler.options.module.rules.unshift({
enforce: plugin.enforce,
include: /.*/,
Expand Down
42 changes: 21 additions & 21 deletions src/webpack/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,27 +58,6 @@ export function getWebpackPlugin<UserOptions = Record<string, never>>(

const externalModules = new Set<string>()

// transform hook
if (plugin.transform) {
const useLoader: RuleSetUseItem[] = [{
loader: `${TRANSFORM_LOADER}?unpluginName=${encodeURIComponent(plugin.name)}`,
}]
const useNone: RuleSetUseItem[] = []
compiler.options.module.rules.unshift({
enforce: plugin.enforce,
use: (data: { resource: string | null; resourceQuery: string }) => {
if (data.resource == null)
return useNone

const id = normalizeAbsolutePath(data.resource + (data.resourceQuery || ''))
if (!plugin.transformInclude || plugin.transformInclude(id))
return useLoader

return useNone
},
})
}

// resolveId hook
if (plugin.resolveId) {
let vfs = compiler.options.plugins.find(i => i instanceof VirtualModulesPlugin) as VirtualModulesPlugin
Expand Down Expand Up @@ -177,6 +156,27 @@ export function getWebpackPlugin<UserOptions = Record<string, never>>(
})
}

// transform hook
if (plugin.transform) {
const useLoader: RuleSetUseItem[] = [{
loader: `${TRANSFORM_LOADER}?unpluginName=${encodeURIComponent(plugin.name)}`,
}]
const useNone: RuleSetUseItem[] = []
compiler.options.module.rules.unshift({
enforce: plugin.enforce,
use: (data: { resource: string | null; resourceQuery: string }) => {
if (data.resource == null)
return useNone

const id = normalizeAbsolutePath(data.resource + (data.resourceQuery || ''))
if (!plugin.transformInclude || plugin.transformInclude(id))
return useLoader

return useNone
},
})
}

if (plugin.webpack)
plugin.webpack(compiler)

Expand Down
35 changes: 35 additions & 0 deletions test/fixtures/load/__test__/build.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { resolve } from 'path'
import fs from 'fs-extra'
import { describe, expect, it } from 'vitest'

const r = (...args: string[]) => resolve(__dirname, '../dist', ...args)

describe('load-called-before-transform', () => {
it('vite', async () => {
const content = await fs.readFile(r('vite/main.js.mjs'), 'utf-8')
expect(content).toContain('it is a msg -> through the load hook -> transform-[Injected Vite]')
})

it('rollup', async () => {
const content = await fs.readFile(r('rollup/main.js'), 'utf-8')

expect(content).toContain('it is a msg -> through the load hook -> transform-[Injected Rollup]')
})

it('webpack', async () => {
const content = await fs.readFile(r('webpack/main.js'), 'utf-8')

expect(content).toContain('it is a msg -> through the load hook -> transform-[Injected Webpack]')
})

it('esbuild', async () => {
const content = await fs.readFile(r('esbuild/main.js'), 'utf-8')
expect(content).toContain('it is a msg -> through the load hook -> transform-[Injected Esbuild]')
})

it.skipIf(process.env.SKIP_RSPACK === 'true')('rspack', async () => {
const content = await fs.readFile(r('rspack/main.js'), 'utf-8')

expect(content).toContain('it is a msg -> through the load hook -> transform-[Injected Rspack]')
})
})
12 changes: 12 additions & 0 deletions test/fixtures/load/esbuild.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const { build } = require('esbuild')
const { esbuild } = require('./unplugin')

build({
entryPoints: ['src/main.js'],
bundle: true,
outdir: 'dist/esbuild',
sourcemap: true,
plugins: [
esbuild({ msg: 'Esbuild' }),
],
})
12 changes: 12 additions & 0 deletions test/fixtures/load/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const { rollup } = require('./unplugin')

export default {
input: './src/main.js',
output: {
dir: './dist/rollup',
sourcemap: true,
},
plugins: [
rollup({ msg: 'Rollup' }),
],
}
14 changes: 14 additions & 0 deletions test/fixtures/load/rspack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const { resolve } = require('path')
const { rspack } = require('./unplugin')

/** @type import('@rspack/core').Configuration */
module.exports = {
mode: 'development',
entry: resolve(__dirname, 'src/main.js'),
output: {
path: resolve(__dirname, 'dist/rspack'),
filename: 'main.js',
},
plugins: [rspack({ msg: 'Rspack' })],
devtool: 'source-map',
}
3 changes: 3 additions & 0 deletions test/fixtures/load/src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import msg1 from './msg'

console.log(msg1)
1 change: 1 addition & 0 deletions test/fixtures/load/src/msg.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 'it is a msg'
45 changes: 45 additions & 0 deletions test/fixtures/load/unplugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const fs = require('fs')
const MagicString = require('magic-string')
const { createUnplugin } = require('unplugin')

const targetFileReg = /(?:\/|\\)msg\.js$/
module.exports = createUnplugin((options) => {
return {
name: 'load-called-before-transform',
loadInclude(id) {
return targetFileReg.test(id)
},
load(id) {
const code = fs.readFileSync(id, { encoding: 'utf-8' })
const str = new MagicString(code)
const _index = code.indexOf('msg')
const loadInjectedCode = 'msg -> through the load hook -> __unplugin__'

str.overwrite(_index, _index + 'msg'.length, loadInjectedCode)
return str.toString()
},
transformInclude(id) {
return targetFileReg.test(id)
},
transform(code, id) {
const s = new MagicString(code)
const index = code.indexOf('__unplugin__')
if (index === -1)
return null

const injectedCode = `transform-[Injected ${options.msg}]`

if (code.includes(injectedCode))
throw new Error('File was already transformed')

s.overwrite(index, index + '__unplugin__'.length, injectedCode)
return {
code: s.toString(),
map: s.generateMap({
source: id,
includeContent: true,
}),
}
},
}
})
18 changes: 18 additions & 0 deletions test/fixtures/load/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const { resolve } = require('path')
const { vite } = require('./unplugin')

module.exports = {
root: __dirname,
plugins: [
vite({ msg: 'Vite' }),
],
build: {
lib: {
entry: resolve(__dirname, 'src/main.js'),
name: 'main',
fileName: 'main.js',
},
outDir: 'dist/vite',
sourcemap: true,
},
}
15 changes: 15 additions & 0 deletions test/fixtures/load/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const { resolve } = require('path')
const { webpack } = require('./unplugin')

module.exports = {
mode: 'development',
entry: resolve(__dirname, 'src/main.js'),
output: {
path: resolve(__dirname, 'dist/webpack'),
filename: 'main.js',
},
plugins: [
webpack({ msg: 'Webpack' }),
],
devtool: 'source-map',
}

0 comments on commit 63e027a

Please sign in to comment.