Skip to content

Commit

Permalink
fix: not include everything for rspack
Browse files Browse the repository at this point in the history
  • Loading branch information
bvanjoi committed Nov 28, 2023
1 parent 1e712c7 commit de77c9d
Show file tree
Hide file tree
Showing 9 changed files with 274 additions and 282 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@
"@ampproject/remapping": "^2.2.1",
"@antfu/eslint-config": "^1.0.0-beta.29",
"@antfu/ni": "^0.21.8",
"@rspack/cli": "^0.3.8",
"@rspack/core": "^0.3.8",
"@rspack/cli": "0.4.0-canary-a9e7d87-20231127152134",
"@rspack/core": "0.4.0-canary-a9e7d87-20231127152134",
"@types/fs-extra": "^11.0.3",
"@types/node": "^20.8.9",
"@types/webpack-sources": "^3.2.2",
Expand Down
401 changes: 172 additions & 229 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

62 changes: 44 additions & 18 deletions src/rspack/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { resolve } from 'path'
import type { RspackPluginInstance, RuleSetUseItem } from '@rspack/core'
import { toArray } from '../utils'
import type { RspackPluginInstance } from '@rspack/core'
import { shouldLoad, toArray, transformUse } from '../utils'
import type {
ResolvedUnpluginOptions,
UnpluginContextMeta,
UnpluginFactory,
UnpluginInstance,
Expand All @@ -10,52 +11,77 @@ import { createRspackContext } from './context'

const TRANSFORM_LOADER = resolve(
__dirname,
__DEV__ ? '../../dist/rspack/loaders/transform' : 'rspack/loaders/transform',
__DEV__ ? '../../dist/rspack/loaders/transform.js' : 'rspack/loaders/transform',
)

const LOAD_LOADER = resolve(
__dirname,
__DEV__ ? '../../dist/rspack/loaders/load' : 'rspack/loaders/load',
__DEV__ ? '../../dist/rspack/loaders/load.js' : 'rspack/loaders/load',
)

const VIRTUAL_MODULE_PREFIX = resolve(process.cwd(), '_virtual_')

export function getRspackPlugin<UserOptions = Record<string, never>>(
factory: UnpluginFactory<UserOptions>,
): UnpluginInstance<UserOptions>['rspack'] {
return (userOptions?: UserOptions): RspackPluginInstance => {
return {
apply(compiler) {
const injected = compiler.$unpluginContext || {}
compiler.$unpluginContext = injected

const meta: UnpluginContextMeta = {
framework: 'rspack',
rspack: {
compiler,
},
}
const rawPlugins = toArray(factory(userOptions!, meta))
for (const plugin of rawPlugins) {
for (const rawPlugin of rawPlugins) {
const plugin = Object.assign(
rawPlugin,
{
__unpluginMeta: meta,
__virtualModulePrefix: VIRTUAL_MODULE_PREFIX,
},
) as ResolvedUnpluginOptions

// inject context object to share with loaders
injected[plugin.name] = plugin

compiler.hooks.thisCompilation.tap(plugin.name, (compilation) => {
if (typeof compilation.hooks.childCompiler === 'undefined')
throw new Error('`compilation.hooks.childCompiler` only support by @rspack/core>=0.4.1')
compilation.hooks.childCompiler.tap(plugin.name, (childCompiler) => {
childCompiler.$unpluginContext = injected
})
})

const externalModules = new Set<string>()

// load hook
if (plugin.load) {
const use: RuleSetUseItem = {
loader: LOAD_LOADER,
options: { plugin },
}
compiler.options.module.rules.unshift({
enforce: plugin.enforce,
include: /.*/,
use,
include(id) {
return shouldLoad(id, plugin, externalModules)
},
use: [{
loader: LOAD_LOADER,
options: {
unpluginName: plugin.name,
},
}],
})
}

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

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

Expand Down
6 changes: 3 additions & 3 deletions src/rspack/loaders/load.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { LoaderContext } from '@rspack/core'
import type { UnpluginContext, UnpluginOptions } from '../../types'
import type { UnpluginContext } from '../../types'
import { createRspackContext } from '../context'
import { normalizeAbsolutePath } from '../../utils'

export default async function load(this: LoaderContext, source: string, map: any) {
const callback = this.async()

const { unpluginName } = this.query as { unpluginName: string }
const plugin = this._compiler?.$unpluginContext[unpluginName]
const id = this.resource
const { plugin } = this.getOptions() as { plugin: UnpluginOptions }

if (!plugin?.load || !id)
return callback(null, source, map)
Expand Down
16 changes: 11 additions & 5 deletions src/rspack/loaders/transform.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { LoaderContext } from '@rspack/core'
import { createRspackContext } from '../context'
import type { UnpluginContext, UnpluginOptions } from '../../types'
import type { UnpluginContext } from '../../types'

export default async function transform(
this: LoaderContext,
Expand All @@ -9,15 +9,21 @@ export default async function transform(
) {
const callback = this.async()

let unpluginName: string
if (typeof this.query === 'string') {
const query = new URLSearchParams(this.query)
unpluginName = query.get('unpluginName')!
}
else {
unpluginName = (this.query as { unpluginName: string }).unpluginName
}

const id = this.resource
const { plugin } = this.getOptions() as { plugin: UnpluginOptions }
const plugin = this._compiler?.$unpluginContext[unpluginName]

if (!plugin?.transform)
return callback(null, source, map)

if (plugin.transformInclude && !plugin.transformInclude(id))
return callback(null, source, map)

const context: UnpluginContext = {
error: error =>
this.emitError(typeof error === 'string' ? new Error(error) : error),
Expand Down
6 changes: 6 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,9 @@ declare module 'webpack' {
$unpluginContext: Record<string, ResolvedUnpluginOptions>
}
}

declare module '@rspack/core' {
interface Compiler {
$unpluginContext: Record<string, ResolvedUnpluginOptions>
}
}
30 changes: 30 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { isAbsolute, normalize } from 'path'
import type { ResolvedUnpluginOptions } from './types'

/**
* Normalizes a given path when it's absolute. Normalizing means returning a new path by converting
Expand Down Expand Up @@ -33,3 +34,32 @@ export function toArray<T>(array?: Nullable<Arrayable<T>>): Array<T> {
return array
return [array]
}

export function shouldLoad(id: string, plugin: ResolvedUnpluginOptions, externalModules: Set<string>): boolean {
if (id.startsWith(plugin.__virtualModulePrefix))
id = decodeURIComponent(id.slice(plugin.__virtualModulePrefix.length))

// load include filter
if (plugin.loadInclude && !plugin.loadInclude(id))
return false

// Don't run load hook for external modules
return !externalModules.has(id)
}

export function transformUse(
data: { resource?: string; resourceQuery?: string },
plugin: ResolvedUnpluginOptions,
transformLoader: string,
) {
if (data.resource == null)
return []

const id = normalizeAbsolutePath(data.resource + (data.resourceQuery || ''))
if (!plugin.transformInclude || plugin.transformInclude(id)) {
return [{
loader: `${transformLoader}?unpluginName=${encodeURIComponent(plugin.name)}`,
}]
}
return []
}
29 changes: 5 additions & 24 deletions src/webpack/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import fs from 'fs'
import { resolve } from 'path'
import process from 'process'
import VirtualModulesPlugin from 'webpack-virtual-modules'
import type { ResolvePluginInstance, RuleSetUseItem } from 'webpack'
import type { ResolvePluginInstance } from 'webpack'
import type { ResolvedUnpluginOptions, UnpluginContextMeta, UnpluginFactory, UnpluginInstance, WebpackCompiler } from '../types'
import { normalizeAbsolutePath, toArray } from '../utils'
import { normalizeAbsolutePath, shouldLoad, toArray, transformUse } from '../utils'
import { createContext } from './context'

const TRANSFORM_LOADER = resolve(
Expand Down Expand Up @@ -136,15 +136,7 @@ export function getWebpackPlugin<UserOptions = Record<string, never>>(
if (plugin.load) {
compiler.options.module.rules.unshift({
include(id) {
if (id.startsWith(plugin.__virtualModulePrefix))
id = decodeURIComponent(id.slice(plugin.__virtualModulePrefix.length))

// load include filter
if (plugin.loadInclude && !plugin.loadInclude(id))
return false

// Don't run load hook for external modules
return !externalModules.has(id)
return shouldLoad(id, plugin, externalModules)
},
enforce: plugin.enforce,
use: [{
Expand All @@ -158,21 +150,10 @@ 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
use(data: { resource?: string; resourceQuery?: string }) {
return transformUse(data, plugin, TRANSFORM_LOADER)
},
})
}
Expand Down
2 changes: 1 addition & 1 deletion test/unit-tests/id-consistency/id-consistency.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ function checkHookCalls(
})
}

describe('id parameter should be consistent accross hooks and plugins', () => {
describe('id parameter should be consistent across hooks and plugins', () => {
afterEach(() => {
vi.restoreAllMocks()
})
Expand Down

0 comments on commit de77c9d

Please sign in to comment.