fix(webpack): resolve loaders to absolute paths

This commit is contained in:
Daniel Roe 2023-07-25 12:50:20 +01:00
parent 98c195f83e
commit 1d847c7514
8 changed files with 46 additions and 37 deletions

View File

@ -1,8 +1,9 @@
import querystring from 'node:querystring'
import { pathToFileURL } from 'node:url'
import { resolve } from 'pathe'
import webpack from 'webpack'
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'
import { logger } from '@nuxt/kit'
import { logger, tryResolveModule } from '@nuxt/kit'
import { joinURL } from 'ufo'
import ForkTSCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin'
@ -46,7 +47,7 @@ function clientPerformance (ctx: WebpackConfigContext) {
}
}
function clientHMR (ctx: WebpackConfigContext) {
async function clientHMR (ctx: WebpackConfigContext) {
if (!ctx.isDev) {
return
}
@ -65,9 +66,10 @@ function clientHMR (ctx: WebpackConfigContext) {
// Add HMR support
const app = (ctx.config.entry as any).app as any
const hotMiddlewarePath = await tryResolveModule('webpack-hot-middleware/client', import.meta.url) || 'webpack-hot-middleware/client'
app.unshift(
// https://github.com/glenjamin/webpack-hot-middleware#config
`webpack-hot-middleware/client?${hotMiddlewareClientOptionsStr}`
`${pathToFileURL(hotMiddlewarePath)}?${hotMiddlewareClientOptionsStr}`
)
ctx.config.plugins = ctx.config.plugins || []

View File

@ -1,12 +1,13 @@
import { tryResolveModule } from '@nuxt/kit'
import type { WebpackConfigContext } from '../utils/config'
import { fileName } from '../utils/config'
export function assets (ctx: WebpackConfigContext) {
export async function assets (ctx: WebpackConfigContext) {
ctx.config.module!.rules!.push(
{
test: /\.(png|jpe?g|gif|svg|webp)$/i,
use: [{
loader: 'url-loader',
loader: await tryResolveModule('url-loader', import.meta.url) ?? 'url-loader',
options: {
...ctx.userConfig.loaders.imgUrl,
name: fileName(ctx, 'img')
@ -16,7 +17,7 @@ export function assets (ctx: WebpackConfigContext) {
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i,
use: [{
loader: 'url-loader',
loader: await tryResolveModule('url-loader', import.meta.url) ?? 'url-loader',
options: {
...ctx.userConfig.loaders.fontUrl,
name: fileName(ctx, 'font')
@ -26,7 +27,7 @@ export function assets (ctx: WebpackConfigContext) {
{
test: /\.(webm|mp4|ogv)$/i,
use: [{
loader: 'file-loader',
loader: await tryResolveModule('file-loader', import.meta.url) ?? 'file-loader',
options: {
...ctx.userConfig.loaders.file,
name: fileName(ctx, 'video')

View File

@ -133,6 +133,8 @@ function baseResolve (ctx: WebpackConfigContext) {
// TODO: this might be refactored as default modulesDir?
const webpackModulesDir = ['node_modules'].concat(ctx.options.modulesDir)
// console.log({webpackModulesDir})
ctx.config.resolve = {
extensions: ['.wasm', '.mjs', '.js', '.ts', '.json', '.vue', '.jsx', '.tsx'],
alias: ctx.alias,
@ -142,7 +144,7 @@ function baseResolve (ctx: WebpackConfigContext) {
}
ctx.config.resolveLoader = {
modules: webpackModulesDir,
// modules: webpackModulesDir,
...ctx.config.resolveLoader
}
}

View File

@ -1,7 +1,8 @@
import { EsbuildPlugin } from 'esbuild-loader'
import { tryResolveModule } from '@nuxt/kit'
import type { WebpackConfigContext } from '../utils/config'
export function esbuild (ctx: WebpackConfigContext) {
export async function esbuild (ctx: WebpackConfigContext) {
// https://esbuild.github.io/getting-started/#bundling-for-the-browser
// https://gs.statcounter.com/browser-version-market-share
// https://nodejs.org/en/
@ -13,7 +14,7 @@ export function esbuild (ctx: WebpackConfigContext) {
ctx.config.module!.rules!.push(
{
test: /\.m?[jt]s$/i,
loader: 'esbuild-loader',
loader: await tryResolveModule('esbuild-loader', import.meta.url) ?? 'esbuild-loader',
exclude: (file) => {
// Not exclude files outside node_modules
file = file.split('node_modules', 2)[1]
@ -32,7 +33,7 @@ export function esbuild (ctx: WebpackConfigContext) {
},
{
test: /\.m?[jt]sx$/,
loader: 'esbuild-loader',
loader: await tryResolveModule('esbuild-loader', import.meta.url) ?? 'esbuild-loader',
options: {
target,
...ctx.nuxt.options.webpack.loaders.esbuild,

View File

@ -1,13 +1,14 @@
import { tryResolveModule } from '@nuxt/kit'
import type { WebpackConfigContext } from '../utils/config'
export function pug (ctx: WebpackConfigContext) {
export async function pug (ctx: WebpackConfigContext) {
ctx.config.module!.rules!.push({
test: /\.pug$/i,
oneOf: [
{
resourceQuery: /^\?vue/i,
use: [{
loader: 'pug-plain-loader',
loader: await tryResolveModule('pug-plain-loader', import.meta.url) ?? 'pug-plain-loader',
options: ctx.userConfig.loaders.pugPlain
}]
},
@ -15,7 +16,7 @@ export function pug (ctx: WebpackConfigContext) {
use: [
'raw-loader',
{
loader: 'pug-plain-loader',
loader: await tryResolveModule('pug-plain-loader', import.meta.url) ?? 'pug-plain-loader',
options: ctx.userConfig.loaders.pugPlain
}
]

View File

@ -1,5 +1,6 @@
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
import CssMinimizerPlugin from 'css-minimizer-webpack-plugin'
import { tryResolveModule } from '@nuxt/kit'
import type { WebpackConfigContext } from '../utils/config'
import { applyPresets, fileName } from '../utils/config'
import { getPostcssConfig } from '../utils/postcss'
@ -31,32 +32,32 @@ function extractCSS (ctx: WebpackConfigContext) {
}
}
function loaders (ctx: WebpackConfigContext) {
async function loaders (ctx: WebpackConfigContext) {
// CSS
ctx.config.module!.rules!.push(createdStyleRule('css', /\.css$/i, null, ctx))
ctx.config.module!.rules!.push(await createdStyleRule('css', /\.css$/i, null, ctx))
// PostCSS
ctx.config.module!.rules!.push(createdStyleRule('postcss', /\.p(ost)?css$/i, null, ctx))
ctx.config.module!.rules!.push(await createdStyleRule('postcss', /\.p(ost)?css$/i, null, ctx))
// Less
const lessLoader = { loader: 'less-loader', options: ctx.userConfig.loaders.less }
ctx.config.module!.rules!.push(createdStyleRule('less', /\.less$/i, lessLoader, ctx))
const lessLoader = { loader: await tryResolveModule('less-loader', import.meta.url) ?? 'less-loader', options: ctx.userConfig.loaders.less }
ctx.config.module!.rules!.push(await createdStyleRule('less', /\.less$/i, lessLoader, ctx))
// Sass (TODO: optional dependency)
const sassLoader = { loader: 'sass-loader', options: ctx.userConfig.loaders.sass }
ctx.config.module!.rules!.push(createdStyleRule('sass', /\.sass$/i, sassLoader, ctx))
const sassLoader = { loader: await tryResolveModule('sass-loader', import.meta.url) ?? 'sass-loader', options: ctx.userConfig.loaders.sass }
ctx.config.module!.rules!.push(await createdStyleRule('sass', /\.sass$/i, sassLoader, ctx))
const scssLoader = { loader: 'sass-loader', options: ctx.userConfig.loaders.scss }
ctx.config.module!.rules!.push(createdStyleRule('scss', /\.scss$/i, scssLoader, ctx))
const scssLoader = { loader: await tryResolveModule('sass-loader', import.meta.url) ?? 'sass-loader', options: ctx.userConfig.loaders.scss }
ctx.config.module!.rules!.push(await createdStyleRule('scss', /\.scss$/i, scssLoader, ctx))
// Stylus
const stylusLoader = { loader: 'stylus-loader', options: ctx.userConfig.loaders.stylus }
ctx.config.module!.rules!.push(createdStyleRule('stylus', /\.styl(us)?$/i, stylusLoader, ctx))
const stylusLoader = { loader: await tryResolveModule('stylus-loader', import.meta.url) ?? 'stylus-loader', options: ctx.userConfig.loaders.stylus }
ctx.config.module!.rules!.push(await createdStyleRule('stylus', /\.styl(us)?$/i, stylusLoader, ctx))
}
function createdStyleRule (lang: string, test: RegExp, processorLoader: any, ctx: WebpackConfigContext) {
async function createdStyleRule (lang: string, test: RegExp, processorLoader: any, ctx: WebpackConfigContext) {
const styleLoaders = [
createPostcssLoadersRule(ctx),
await createPostcssLoadersRule(ctx),
processorLoader
].filter(Boolean)
@ -64,8 +65,8 @@ function createdStyleRule (lang: string, test: RegExp, processorLoader: any, ctx
ctx.userConfig.loaders.cssModules.importLoaders =
styleLoaders.length
const cssLoaders = createCssLoadersRule(ctx, ctx.userConfig.loaders.css)
const cssModuleLoaders = createCssLoadersRule(ctx, ctx.userConfig.loaders.cssModules)
const cssLoaders = await createCssLoadersRule(ctx, ctx.userConfig.loaders.css)
const cssModuleLoaders = await createCssLoadersRule(ctx, ctx.userConfig.loaders.cssModules)
return {
test,
@ -83,8 +84,8 @@ function createdStyleRule (lang: string, test: RegExp, processorLoader: any, ctx
}
}
function createCssLoadersRule (ctx: WebpackConfigContext, cssLoaderOptions: any) {
const cssLoader = { loader: 'css-loader', options: cssLoaderOptions }
async function createCssLoadersRule (ctx: WebpackConfigContext, cssLoaderOptions: any) {
const cssLoader = { loader: await tryResolveModule('css-loader', import.meta.url) ?? 'css-loader', options: cssLoaderOptions }
if (ctx.userConfig.extractCSS) {
if (ctx.isServer) {
@ -106,14 +107,14 @@ function createCssLoadersRule (ctx: WebpackConfigContext, cssLoaderOptions: any)
return [
// https://github.com/vuejs/vue-style-loader/issues/56
// {
// loader: 'vue-style-loader',
// loader: await tryResolveModule('vue-style-loader', import.meta.url) ?? 'vue-style-loader',
// options: options.webpack.loaders.vueStyle
// },
cssLoader
]
}
function createPostcssLoadersRule (ctx: WebpackConfigContext) {
async function createPostcssLoadersRule (ctx: WebpackConfigContext) {
if (!ctx.options.postcss) { return }
const config = getPostcssConfig(ctx.nuxt)
@ -123,7 +124,7 @@ function createPostcssLoadersRule (ctx: WebpackConfigContext) {
}
return {
loader: 'postcss-loader',
loader: await tryResolveModule('postcss-loader', import.meta.url) ?? 'postcss-loader',
options: config
}
}

View File

@ -1,17 +1,18 @@
import { resolve } from 'pathe'
import VueLoaderPlugin from 'vue-loader/dist/pluginWebpack5.js'
import webpack from 'webpack'
import { tryResolveModule } from '@nuxt/kit'
import VueSSRClientPlugin from '../plugins/vue/client'
import VueSSRServerPlugin from '../plugins/vue/server'
import type { WebpackConfigContext } from '../utils/config'
export function vue (ctx: WebpackConfigContext) {
export async function vue (ctx: WebpackConfigContext) {
// @ts-expect-error de-default vue-loader
ctx.config.plugins!.push(new (VueLoaderPlugin.default || VueLoaderPlugin)())
ctx.config.module!.rules!.push({
test: /\.vue$/i,
loader: 'vue-loader',
loader: await tryResolveModule('vue-loader', import.meta.url) ?? 'vue-loader',
options: {
reactivityTransform: ctx.nuxt.options.experimental.reactivityTransform,
...ctx.userConfig.loaders.vue

View File

@ -130,7 +130,7 @@ export default defineNuxtConfig({
// in order to test bigint serialisation we need to set target to a more modern one
for (const config of configs) {
const esbuildRules = config.module!.rules!.filter(
rule => typeof rule === 'object' && rule && 'loader' in rule && rule.loader === 'esbuild-loader'
rule => typeof rule === 'object' && rule && 'loader' in rule && rule.loader?.includes('esbuild-loader')
)
for (const rule of esbuildRules) {
if (typeof rule === 'object' && typeof rule.options === 'object') {