#![allow(
    clippy::derive_partial_eq_without_eq,
    clippy::empty_enums,
    clippy::unreadable_literal
)]
#![cfg_attr(feature = "unstable", feature(never_type))]

use serde::de::{Deserialize, IntoDeserializer};
use serde_derive::Deserialize;
use serde_test::{assert_de_tokens_error, Token};
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::ffi::{CStr, CString};
use std::num::{
    NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,
    NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, Wrapping,
};
use std::time::{Duration, SystemTime};

#[derive(Copy, Clone, PartialEq, Debug, Deserialize)]
struct UnitStruct;

#[derive(PartialEq, Debug, Deserialize)]
struct Struct {
    a: i32,
    b: i32,
    #[serde(skip_deserializing)]
    c: i32,
}

#[derive(PartialEq, Debug, Deserialize)]
#[serde(deny_unknown_fields)]
struct StructDenyUnknown {
    a: i32,
    #[serde(skip_deserializing)]
    b: i32,
}

#[derive(PartialEq, Debug, Deserialize)]
#[serde(deny_unknown_fields)]
struct StructSkipAllDenyUnknown {
    #[serde(skip_deserializing)]
    a: i32,
}

#[derive(Default, PartialEq, Debug)]
struct NotDeserializable;

#[derive(PartialEq, Debug, Deserialize)]
enum Enum {
    #[allow(dead_code)]
    #[serde(skip_deserializing)]
    Skipped,
    Unit,
    Simple(i32),
    Seq(i32, i32, i32),
    Map {
        a: i32,
        b: i32,
        c: i32,
    },
    SimpleWithSkipped(#[serde(skip_deserializing)] NotDeserializable),
}

#[derive(PartialEq, Debug, Deserialize)]
enum EnumSkipAll {
    #[allow(dead_code)]
    #[serde(skip_deserializing)]
    Skipped,
}

#[test]
fn test_i8() {
    let test = assert_de_tokens_error::<i8>;

    // from signed
    test(
        &[Token::I16(-129)],
        "invalid value: integer `-129`, expected i8",
    );
    test(
        &[Token::I32(-129)],
        "invalid value: integer `-129`, expected i8",
    );
    test(
        &[Token::I64(-129)],
        "invalid value: integer `-129`, expected i8",
    );
    test(
        &[Token::I16(128)],
        "invalid value: integer `128`, expected i8",
    );
    test(
        &[Token::I32(128)],
        "invalid value: integer `128`, expected i8",
    );
    test(
        &[Token::I64(128)],
        "invalid value: integer `128`, expected i8",
    );

    // from unsigned
    test(
        &[Token::U8(128)],
        "invalid value: integer `128`, expected i8",
    );
    test(
        &[Token::U16(128)],
        "invalid value: integer `128`, expected i8",
    );
    test(
        &[Token::U32(128)],
        "invalid value: integer `128`, expected i8",
    );
    test(
        &[Token::U64(128)],
        "invalid value: integer `128`, expected i8",
    );
}

#[test]
fn test_i16() {
    let test = assert_de_tokens_error::<i16>;

    // from signed
    test(
        &[Token::I32(-32769)],
        "invalid value: integer `-32769`, expected i16",
    );
    test(
        &[Token::I64(-32769)],
        "invalid value: integer `-32769`, expected i16",
    );
    test(
        &[Token::I32(32768)],
        "invalid value: integer `32768`, expected i16",
    );
    test(
        &[Token::I64(32768)],
        "invalid value: integer `32768`, expected i16",
    );

    // from unsigned
    test(
        &[Token::U16(32768)],
        "invalid value: integer `32768`, expected i16",
    );
    test(
        &[Token::U32(32768)],
        "invalid value: integer `32768`, expected i16",
    );
    test(
        &[Token::U64(32768)],
        "invalid value: integer `32768`, expected i16",
    );
}

#[test]
fn test_i32() {
    let test = assert_de_tokens_error::<i32>;

    // from signed
    test(
        &[Token::I64(-2147483649)],
        "invalid value: integer `-2147483649`, expected i32",
    );
    test(
        &[Token::I64(2147483648)],
        "invalid value: integer `2147483648`, expected i32",
    );

    // from unsigned
    test(
        &[Token::U32(2147483648)],
        "invalid value: integer `2147483648`, expected i32",
    );
    test(
        &[Token::U64(2147483648)],
        "invalid value: integer `2147483648`, expected i32",
    );
}

#[test]
fn test_i64() {
    let test = assert_de_tokens_error::<i64>;

    // from unsigned
    test(
        &[Token::U64(9223372036854775808)],
        "invalid value: integer `9223372036854775808`, expected i64",
    );
}

#[test]
fn test_i128() {
    let deserializer = <i128 as IntoDeserializer>::into_deserializer(1);
    let error = <&str>::deserialize(deserializer).unwrap_err();
    assert_eq!(
        error.to_string(),
        "invalid type: integer `1` as i128, expected a borrowed string",
    );
}

#[test]
fn test_u8() {
    let test = assert_de_tokens_error::<u8>;

    // from signed
    test(&[Token::I8(-1)], "invalid value: integer `-1`, expected u8");
    test(
        &[Token::I16(-1)],
        "invalid value: integer `-1`, expected u8",
    );
    test(
        &[Token::I32(-1)],
        "invalid value: integer `-1`, expected u8",
    );
    test(
        &[Token::I64(-1)],
        "invalid value: integer `-1`, expected u8",
    );
    test(
        &[Token::I16(256)],
        "invalid value: integer `256`, expected u8",
    );
    test(
        &[Token::I32(256)],
        "invalid value: integer `256`, expected u8",
    );
    test(
        &[Token::I64(256)],
        "invalid value: integer `256`, expected u8",
    );

    // from unsigned
    test(
        &[Token::U16(256)],
        "invalid value: integer `256`, expected u8",
    );
    test(
        &[Token::U32(256)],
        "invalid value: integer `256`, expected u8",
    );
    test(
        &[Token::U64(256)],
        "invalid value: integer `256`, expected u8",
    );
}

#[test]
fn test_u16() {
    let test = assert_de_tokens_error::<u16>;

    // from signed
    test(
        &[Token::I8(-1)],
        "invalid value: integer `-1`, expected u16",
    );
    test(
        &[Token::I16(-1)],
        "invalid value: integer `-1`, expected u16",
    );
    test(
        &[Token::I32(-1)],
        "invalid value: integer `-1`, expected u16",
    );
    test(
        &[Token::I64(-1)],
        "invalid value: integer `-1`, expected u16",
    );
    test(
        &[Token::I32(65536)],
        "invalid value: integer `65536`, expected u16",
    );
    test(
        &[Token::I64(65536)],
        "invalid value: integer `65536`, expected u16",
    );

    // from unsigned
    test(
        &[Token::U32(65536)],
        "invalid value: integer `65536`, expected u16",
    );
    test(
        &[Token::U64(65536)],
        "invalid value: integer `65536`, expected u16",
    );
}

#[test]
fn test_u32() {
    let test = assert_de_tokens_error::<u32>;

    // from signed
    test(
        &[Token::I8(-1)],
        "invalid value: integer `-1`, expected u32",
    );
    test(
        &[Token::I16(-1)],
        "invalid value: integer `-1`, expected u32",
    );
    test(
        &[Token::I32(-1)],
        "invalid value: integer `-1`, expected u32",
    );
    test(
        &[Token::I64(-1)],
        "invalid value: integer `-1`, expected u32",
    );
    test(
        &[Token::I64(4294967296)],
        "invalid value: integer `4294967296`, expected u32",
    );

    // from unsigned
    test(
        &[Token::U64(4294967296)],
        "invalid value: integer `4294967296`, expected u32",
    );
}

#[test]
fn test_u64() {
    let test = assert_de_tokens_error::<u64>;

    // from signed
    test(
        &[Token::I8(-1)],
        "invalid value: integer `-1`, expected u64",
    );
    test(
        &[Token::I16(-1)],
        "invalid value: integer `-1`, expected u64",
    );
    test(
        &[Token::I32(-1)],
        "invalid value: integer `-1`, expected u64",
    );
    test(
        &[Token::I64(-1)],
        "invalid value: integer `-1`, expected u64",
    );

    let deserializer = <u64 as IntoDeserializer>::into_deserializer(1);
    let error = <&str>::deserialize(deserializer).unwrap_err();
    assert_eq!(
        error.to_string(),
        "invalid type: integer `1`, expected a borrowed string",
    );
}

#[test]
fn test_u128() {
    let test = assert_de_tokens_error::<u128>;

    // from signed
    test(
        &[Token::I8(-1)],
        "invalid value: integer `-1`, expected u128",
    );
    test(
        &[Token::I16(-1)],
        "invalid value: integer `-1`, expected u128",
    );
    test(
        &[Token::I32(-1)],
        "invalid value: integer `-1`, expected u128",
    );
    test(
        &[Token::I64(-1)],
        "invalid value: integer `-1`, expected u128",
    );

    let deserializer = <u128 as IntoDeserializer>::into_deserializer(1);
    let error = <&str>::deserialize(deserializer).unwrap_err();
    assert_eq!(
        error.to_string(),
        "invalid type: integer `1` as u128, expected a borrowed string",
    );
}

#[test]
fn test_usize() {
    let test = assert_de_tokens_error::<usize>;

    // from signed
    test(
        &[Token::I8(-1)],
        "invalid value: integer `-1`, expected usize",
    );
    test(
        &[Token::I16(-1)],
        "invalid value: integer `-1`, expected usize",
    );
    test(
        &[Token::I32(-1)],
        "invalid value: integer `-1`, expected usize",
    );
    test(
        &[Token::I64(-1)],
        "invalid value: integer `-1`, expected usize",
    );
}

#[test]
fn test_nonzero_i8() {
    let test = assert_de_tokens_error::<NonZeroI8>;

    // from zero
    test(
        &[Token::I8(0)],
        "invalid value: integer `0`, expected a nonzero i8",
    );
    test(
        &[Token::I16(0)],
        "invalid value: integer `0`, expected a nonzero i8",
    );
    test(
        &[Token::I32(0)],
        "invalid value: integer `0`, expected a nonzero i8",
    );
    test(
        &[Token::I64(0)],
        "invalid value: integer `0`, expected a nonzero i8",
    );
    test(
        &[Token::U8(0)],
        "invalid value: integer `0`, expected a nonzero i8",
    );
    test(
        &[Token::U16(0)],
        "invalid value: integer `0`, expected a nonzero i8",
    );
    test(
        &[Token::U32(0)],
        "invalid value: integer `0`, expected a nonzero i8",
    );
    test(
        &[Token::U64(0)],
        "invalid value: integer `0`, expected a nonzero i8",
    );

    // from signed
    test(
        &[Token::I16(-129)],
        "invalid value: integer `-129`, expected a nonzero i8",
    );
    test(
        &[Token::I32(-129)],
        "invalid value: integer `-129`, expected a nonzero i8",
    );
    test(
        &[Token::I64(-129)],
        "invalid value: integer `-129`, expected a nonzero i8",
    );
    test(
        &[Token::I16(128)],
        "invalid value: integer `128`, expected a nonzero i8",
    );
    test(
        &[Token::I32(128)],
        "invalid value: integer `128`, expected a nonzero i8",
    );
    test(
        &[Token::I64(128)],
        "invalid value: integer `128`, expected a nonzero i8",
    );

    // from unsigned
    test(
        &[Token::U8(128)],
        "invalid value: integer `128`, expected a nonzero i8",
    );
    test(
        &[Token::U16(128)],
        "invalid value: integer `128`, expected a nonzero i8",
    );
    test(
        &[Token::U32(128)],
        "invalid value: integer `128`, expected a nonzero i8",
    );
    test(
        &[Token::U64(128)],
        "invalid value: integer `128`, expected a nonzero i8",
    );
}

#[test]
fn test_nonzero_i16() {
    let test = assert_de_tokens_error::<NonZeroI16>;

    // from zero
    test(
        &[Token::I8(0)],
        "invalid value: integer `0`, expected a nonzero i16",
    );
    test(
        &[Token::I16(0)],
        "invalid value: integer `0`, expected a nonzero i16",
    );
    test(
        &[Token::I32(0)],
        "invalid value: integer `0`, expected a nonzero i16",
    );
    test(
        &[Token::I64(0)],
        "invalid value: integer `0`, expected a nonzero i16",
    );
    test(
        &[Token::U8(0)],
        "invalid value: integer `0`, expected a nonzero i16",
    );
    test(
        &[Token::U16(0)],
        "invalid value: integer `0`, expected a nonzero i16",
    );
    test(
        &[Token::U32(0)],
        "invalid value: integer `0`, expected a nonzero i16",
    );
    test(
        &[Token::U64(0)],
        "invalid value: integer `0`, expected a nonzero i16",
    );

    // from signed
    test(
        &[Token::I32(-32769)],
        "invalid value: integer `-32769`, expected a nonzero i16",
    );
    test(
        &[Token::I64(-32769)],
        "invalid value: integer `-32769`, expected a nonzero i16",
    );
    test(
        &[Token::I32(32768)],
        "invalid value: integer `32768`, expected a nonzero i16",
    );
    test(
        &[Token::I64(32768)],
        "invalid value: integer `32768`, expected a nonzero i16",
    );

    // from unsigned
    test(
        &[Token::U16(32768)],
        "invalid value: integer `32768`, expected a nonzero i16",
    );
    test(
        &[Token::U32(32768)],
        "invalid value: integer `32768`, expected a nonzero i16",
    );
    test(
        &[Token::U64(32768)],
        "invalid value: integer `32768`, expected a nonzero i16",
    );
}

#[test]
fn test_nonzero_i32() {
    let test = assert_de_tokens_error::<NonZeroI32>;

    // from zero
    test(
        &[Token::I8(0)],
        "invalid value: integer `0`, expected a nonzero i32",
    );
    test(
        &[Token::I16(0)],
        "invalid value: integer `0`, expected a nonzero i32",
    );
    test(
        &[Token::I32(0)],
        "invalid value: integer `0`, expected a nonzero i32",
    );
    test(
        &[Token::I64(0)],
        "invalid value: integer `0`, expected a nonzero i32",
    );
    test(
        &[Token::U8(0)],
        "invalid value: integer `0`, expected a nonzero i32",
    );
    test(
        &[Token::U16(0)],
        "invalid value: integer `0`, expected a nonzero i32",
    );
    test(
        &[Token::U32(0)],
        "invalid value: integer `0`, expected a nonzero i32",
    );
    test(
        &[Token::U64(0)],
        "invalid value: integer `0`, expected a nonzero i32",
    );

    // from signed
    test(
        &[Token::I64(-2147483649)],
        "invalid value: integer `-2147483649`, expected a nonzero i32",
    );
    test(
        &[Token::I64(2147483648)],
        "invalid value: integer `2147483648`, expected a nonzero i32",
    );

    // from unsigned
    test(
        &[Token::U32(2147483648)],
        "invalid value: integer `2147483648`, expected a nonzero i32",
    );
    test(
        &[Token::U64(2147483648)],
        "invalid value: integer `2147483648`, expected a nonzero i32",
    );
}

#[test]
fn test_nonzero_i64() {
    let test = assert_de_tokens_error::<NonZeroI64>;

    // from zero
    test(
        &[Token::I8(0)],
        "invalid value: integer `0`, expected a nonzero i64",
    );
    test(
        &[Token::I16(0)],
        "invalid value: integer `0`, expected a nonzero i64",
    );
    test(
        &[Token::I32(0)],
        "invalid value: integer `0`, expected a nonzero i64",
    );
    test(
        &[Token::I64(0)],
        "invalid value: integer `0`, expected a nonzero i64",
    );
    test(
        &[Token::U8(0)],
        "invalid value: integer `0`, expected a nonzero i64",
    );
    test(
        &[Token::U16(0)],
        "invalid value: integer `0`, expected a nonzero i64",
    );
    test(
        &[Token::U32(0)],
        "invalid value: integer `0`, expected a nonzero i64",
    );
    test(
        &[Token::U64(0)],
        "invalid value: integer `0`, expected a nonzero i64",
    );

    // from unsigned
    test(
        &[Token::U64(9223372036854775808)],
        "invalid value: integer `9223372036854775808`, expected a nonzero i64",
    );
}

#[test]
fn test_nonzero_i128() {
    let test = assert_de_tokens_error::<NonZeroI128>;

    // from zero
    test(
        &[Token::I8(0)],
        "invalid value: integer `0`, expected a nonzero i128",
    );
    test(
        &[Token::I16(0)],
        "invalid value: integer `0`, expected a nonzero i128",
    );
    test(
        &[Token::I32(0)],
        "invalid value: integer `0`, expected a nonzero i128",
    );
    test(
        &[Token::I64(0)],
        "invalid value: integer `0`, expected a nonzero i128",
    );
    test(
        &[Token::U8(0)],
        "invalid value: integer `0`, expected a nonzero i128",
    );
    test(
        &[Token::U16(0)],
        "invalid value: integer `0`, expected a nonzero i128",
    );
    test(
        &[Token::U32(0)],
        "invalid value: integer `0`, expected a nonzero i128",
    );
    test(
        &[Token::U64(0)],
        "invalid value: integer `0`, expected a nonzero i128",
    );
}

#[test]
fn test_nonzero_isize() {
    let test = assert_de_tokens_error::<NonZeroIsize>;

    // from zero
    test(
        &[Token::I8(0)],
        "invalid value: integer `0`, expected a nonzero isize",
    );
    test(
        &[Token::I16(0)],
        "invalid value: integer `0`, expected a nonzero isize",
    );
    test(
        &[Token::I32(0)],
        "invalid value: integer `0`, expected a nonzero isize",
    );
    test(
        &[Token::I64(0)],
        "invalid value: integer `0`, expected a nonzero isize",
    );
    test(
        &[Token::U8(0)],
        "invalid value: integer `0`, expected a nonzero isize",
    );
    test(
        &[Token::U16(0)],
        "invalid value: integer `0`, expected a nonzero isize",
    );
    test(
        &[Token::U32(0)],
        "invalid value: integer `0`, expected a nonzero isize",
    );
    test(
        &[Token::U64(0)],
        "invalid value: integer `0`, expected a nonzero isize",
    );
}

#[test]
fn test_nonzero_u8() {
    let test = assert_de_tokens_error::<NonZeroU8>;

    // from zero
    test(
        &[Token::I8(0)],
        "invalid value: integer `0`, expected a nonzero u8",
    );
    test(
        &[Token::I16(0)],
        "invalid value: integer `0`, expected a nonzero u8",
    );
    test(
        &[Token::I32(0)],
        "invalid value: integer `0`, expected a nonzero u8",
    );
    test(
        &[Token::I64(0)],
        "invalid value: integer `0`, expected a nonzero u8",
    );
    test(
        &[Token::U8(0)],
        "invalid value: integer `0`, expected a nonzero u8",
    );
    test(
        &[Token::U16(0)],
        "invalid value: integer `0`, expected a nonzero u8",
    );
    test(
        &[Token::U32(0)],
        "invalid value: integer `0`, expected a nonzero u8",
    );
    test(
        &[Token::U64(0)],
        "invalid value: integer `0`, expected a nonzero u8",
    );

    // from signed
    test(
        &[Token::I8(-1)],
        "invalid value: integer `-1`, expected a nonzero u8",
    );
    test(
        &[Token::I16(-1)],
        "invalid value: integer `-1`, expected a nonzero u8",
    );
    test(
        &[Token::I32(-1)],
        "invalid value: integer `-1`, expected a nonzero u8",
    );
    test(
        &[Token::I64(-1)],
        "invalid value: integer `-1`, expected a nonzero u8",
    );
    test(
        &[Token::I16(256)],
        "invalid value: integer `256`, expected a nonzero u8",
    );
    test(
        &[Token::I32(256)],
        "invalid value: integer `256`, expected a nonzero u8",
    );
    test(
        &[Token::I64(256)],
        "invalid value: integer `256`, expected a nonzero u8",
    );

    // from unsigned
    test(
        &[Token::U16(256)],
        "invalid value: integer `256`, expected a nonzero u8",
    );
    test(
        &[Token::U32(256)],
        "invalid value: integer `256`, expected a nonzero u8",
    );
    test(
        &[Token::U64(256)],
        "invalid value: integer `256`, expected a nonzero u8",
    );
}

#[test]
fn test_nonzero_u16() {
    let test = assert_de_tokens_error::<NonZeroU16>;

    // from zero
    test(
        &[Token::I8(0)],
        "invalid value: integer `0`, expected a nonzero u16",
    );
    test(
        &[Token::I16(0)],
        "invalid value: integer `0`, expected a nonzero u16",
    );
    test(
        &[Token::I32(0)],
        "invalid value: integer `0`, expected a nonzero u16",
    );
    test(
        &[Token::I64(0)],
        "invalid value: integer `0`, expected a nonzero u16",
    );
    test(
        &[Token::U8(0)],
        "invalid value: integer `0`, expected a nonzero u16",
    );
    test(
        &[Token::U16(0)],
        "invalid value: integer `0`, expected a nonzero u16",
    );
    test(
        &[Token::U32(0)],
        "invalid value: integer `0`, expected a nonzero u16",
    );
    test(
        &[Token::U64(0)],
        "invalid value: integer `0`, expected a nonzero u16",
    );

    // from signed
    test(
        &[Token::I8(-1)],
        "invalid value: integer `-1`, expected a nonzero u16",
    );
    test(
        &[Token::I16(-1)],
        "invalid value: integer `-1`, expected a nonzero u16",
    );
    test(
        &[Token::I32(-1)],
        "invalid value: integer `-1`, expected a nonzero u16",
    );
    test(
        &[Token::I64(-1)],
        "invalid value: integer `-1`, expected a nonzero u16",
    );
    test(
        &[Token::I32(65536)],
        "invalid value: integer `65536`, expected a nonzero u16",
    );
    test(
        &[Token::I64(65536)],
        "invalid value: integer `65536`, expected a nonzero u16",
    );

    // from unsigned
    test(
        &[Token::U32(65536)],
        "invalid value: integer `65536`, expected a nonzero u16",
    );
    test(
        &[Token::U64(65536)],
        "invalid value: integer `65536`, expected a nonzero u16",
    );
}

#[test]
fn test_nonzero_u32() {
    let test = assert_de_tokens_error::<NonZeroU32>;

    // from zero
    test(
        &[Token::I8(0)],
        "invalid value: integer `0`, expected a nonzero u32",
    );
    test(
        &[Token::I16(0)],
        "invalid value: integer `0`, expected a nonzero u32",
    );
    test(
        &[Token::I32(0)],
        "invalid value: integer `0`, expected a nonzero u32",
    );
    test(
        &[Token::I64(0)],
        "invalid value: integer `0`, expected a nonzero u32",
    );
    test(
        &[Token::U8(0)],
        "invalid value: integer `0`, expected a nonzero u32",
    );
    test(
        &[Token::U16(0)],
        "invalid value: integer `0`, expected a nonzero u32",
    );
    test(
        &[Token::U32(0)],
        "invalid value: integer `0`, expected a nonzero u32",
    );
    test(
        &[Token::U64(0)],
        "invalid value: integer `0`, expected a nonzero u32",
    );

    // from signed
    test(
        &[Token::I8(-1)],
        "invalid value: integer `-1`, expected a nonzero u32",
    );
    test(
        &[Token::I16(-1)],
        "invalid value: integer `-1`, expected a nonzero u32",
    );
    test(
        &[Token::I32(-1)],
        "invalid value: integer `-1`, expected a nonzero u32",
    );
    test(
        &[Token::I64(-1)],
        "invalid value: integer `-1`, expected a nonzero u32",
    );
    test(
        &[Token::I64(4294967296)],
        "invalid value: integer `4294967296`, expected a nonzero u32",
    );

    // from unsigned
    test(
        &[Token::U64(4294967296)],
        "invalid value: integer `4294967296`, expected a nonzero u32",
    );
}

#[test]
fn test_nonzero_u64() {
    let test = assert_de_tokens_error::<NonZeroU64>;

    // from zero
    test(
        &[Token::I8(0)],
        "invalid value: integer `0`, expected a nonzero u64",
    );
    test(
        &[Token::I16(0)],
        "invalid value: integer `0`, expected a nonzero u64",
    );
    test(
        &[Token::I32(0)],
        "invalid value: integer `0`, expected a nonzero u64",
    );
    test(
        &[Token::I64(0)],
        "invalid value: integer `0`, expected a nonzero u64",
    );
    test(
        &[Token::U8(0)],
        "invalid value: integer `0`, expected a nonzero u64",
    );
    test(
        &[Token::U16(0)],
        "invalid value: integer `0`, expected a nonzero u64",
    );
    test(
        &[Token::U32(0)],
        "invalid value: integer `0`, expected a nonzero u64",
    );
    test(
        &[Token::U64(0)],
        "invalid value: integer `0`, expected a nonzero u64",
    );

    // from signed
    test(
        &[Token::I8(-1)],
        "invalid value: integer `-1`, expected a nonzero u64",
    );
    test(
        &[Token::I16(-1)],
        "invalid value: integer `-1`, expected a nonzero u64",
    );
    test(
        &[Token::I32(-1)],
        "invalid value: integer `-1`, expected a nonzero u64",
    );
    test(
        &[Token::I64(-1)],
        "invalid value: integer `-1`, expected a nonzero u64",
    );
}

#[test]
fn test_nonzero_u128() {
    let test = assert_de_tokens_error::<NonZeroU128>;

    // from zero
    test(
        &[Token::I8(0)],
        "invalid value: integer `0`, expected a nonzero u128",
    );
    test(
        &[Token::I16(0)],
        "invalid value: integer `0`, expected a nonzero u128",
    );
    test(
        &[Token::I32(0)],
        "invalid value: integer `0`, expected a nonzero u128",
    );
    test(
        &[Token::I64(0)],
        "invalid value: integer `0`, expected a nonzero u128",
    );
    test(
        &[Token::U8(0)],
        "invalid value: integer `0`, expected a nonzero u128",
    );
    test(
        &[Token::U16(0)],
        "invalid value: integer `0`, expected a nonzero u128",
    );
    test(
        &[Token::U32(0)],
        "invalid value: integer `0`, expected a nonzero u128",
    );
    test(
        &[Token::U64(0)],
        "invalid value: integer `0`, expected a nonzero u128",
    );

    // from signed
    test(
        &[Token::I8(-1)],
        "invalid value: integer `-1`, expected a nonzero u128",
    );
    test(
        &[Token::I16(-1)],
        "invalid value: integer `-1`, expected a nonzero u128",
    );
    test(
        &[Token::I32(-1)],
        "invalid value: integer `-1`, expected a nonzero u128",
    );
    test(
        &[Token::I64(-1)],
        "invalid value: integer `-1`, expected a nonzero u128",
    );
}

#[test]
fn test_nonzero_usize() {
    let test = assert_de_tokens_error::<NonZeroUsize>;

    // from zero
    test(
        &[Token::I8(0)],
        "invalid value: integer `0`, expected a nonzero usize",
    );
    test(
        &[Token::I16(0)],
        "invalid value: integer `0`, expected a nonzero usize",
    );
    test(
        &[Token::I32(0)],
        "invalid value: integer `0`, expected a nonzero usize",
    );
    test(
        &[Token::I64(0)],
        "invalid value: integer `0`, expected a nonzero usize",
    );
    test(
        &[Token::U8(0)],
        "invalid value: integer `0`, expected a nonzero usize",
    );
    test(
        &[Token::U16(0)],
        "invalid value: integer `0`, expected a nonzero usize",
    );
    test(
        &[Token::U32(0)],
        "invalid value: integer `0`, expected a nonzero usize",
    );
    test(
        &[Token::U64(0)],
        "invalid value: integer `0`, expected a nonzero usize",
    );

    // from signed
    test(
        &[Token::I8(-1)],
        "invalid value: integer `-1`, expected a nonzero usize",
    );
    test(
        &[Token::I16(-1)],
        "invalid value: integer `-1`, expected a nonzero usize",
    );
    test(
        &[Token::I32(-1)],
        "invalid value: integer `-1`, expected a nonzero usize",
    );
    test(
        &[Token::I64(-1)],
        "invalid value: integer `-1`, expected a nonzero usize",
    );
}

#[test]
fn test_unknown_field() {
    assert_de_tokens_error::<StructDenyUnknown>(
        &[
            Token::Struct {
                name: "StructDenyUnknown",
                len: 1,
            },
            Token::Str("a"),
            Token::I32(0),
            Token::Str("d"),
        ],
        "unknown field `d`, expected `a`",
    );
}

#[test]
fn test_skipped_field_is_unknown() {
    assert_de_tokens_error::<StructDenyUnknown>(
        &[
            Token::Struct {
                name: "StructDenyUnknown",
                len: 1,
            },
            Token::Str("b"),
        ],
        "unknown field `b`, expected `a`",
    );
}

#[test]
fn test_skip_all_deny_unknown() {
    assert_de_tokens_error::<StructSkipAllDenyUnknown>(
        &[
            Token::Struct {
                name: "StructSkipAllDenyUnknown",
                len: 0,
            },
            Token::Str("a"),
        ],
        "unknown field `a`, there are no fields",
    );
}

#[test]
fn test_unknown_variant() {
    assert_de_tokens_error::<Enum>(
    &[
        Token::UnitVariant { name: "Enum", variant: "Foo" },
    ],
    "unknown variant `Foo`, expected one of `Unit`, `Simple`, `Seq`, `Map`, `SimpleWithSkipped`",
    );
}

#[test]
fn test_enum_skipped_variant() {
    assert_de_tokens_error::<Enum>(
    &[
        Token::UnitVariant { name: "Enum", variant: "Skipped" },
    ],
    "unknown variant `Skipped`, expected one of `Unit`, `Simple`, `Seq`, `Map`, `SimpleWithSkipped`",
    );
}

#[test]
fn test_enum_skip_all() {
    assert_de_tokens_error::<EnumSkipAll>(
        &[Token::UnitVariant {
            name: "EnumSkipAll",
            variant: "Skipped",
        }],
        "unknown variant `Skipped`, there are no variants",
    );
}

#[test]
fn test_duplicate_field_struct() {
    assert_de_tokens_error::<Struct>(
        &[
            Token::Map { len: Some(3) },
            Token::Str("a"),
            Token::I32(1),
            Token::Str("a"),
        ],
        "duplicate field `a`",
    );
}

#[test]
fn test_duplicate_field_enum() {
    assert_de_tokens_error::<Enum>(
        &[
            Token::StructVariant {
                name: "Enum",
                variant: "Map",
                len: 3,
            },
            Token::Str("a"),
            Token::I32(1),
            Token::Str("a"),
        ],
        "duplicate field `a`",
    );
}

#[test]
fn test_enum_out_of_range() {
    assert_de_tokens_error::<Enum>(
        &[Token::Enum { name: "Enum" }, Token::U32(5), Token::Unit],
        "invalid value: integer `5`, expected variant index 0 <= i < 5",
    );
}

#[test]
fn test_short_tuple() {
    assert_de_tokens_error::<(u8, u8, u8)>(
        &[Token::Tuple { len: 1 }, Token::U8(1), Token::TupleEnd],
        "invalid length 1, expected a tuple of size 3",
    );
}

#[test]
fn test_short_array() {
    assert_de_tokens_error::<[u8; 3]>(
        &[Token::Seq { len: Some(1) }, Token::U8(1), Token::SeqEnd],
        "invalid length 1, expected an array of length 3",
    );
}

#[test]
fn test_cstring_internal_null() {
    assert_de_tokens_error::<CString>(
        &[Token::Bytes(b"a\0c")],
        "nul byte found in provided data at position: 1",
    );
}

#[test]
fn test_cstring_internal_null_end() {
    assert_de_tokens_error::<CString>(
        &[Token::Bytes(b"ac\0")],
        "nul byte found in provided data at position: 2",
    );
}

#[test]
fn test_unit_from_empty_seq() {
    assert_de_tokens_error::<()>(
        &[Token::Seq { len: Some(0) }, Token::SeqEnd],
        "invalid type: sequence, expected unit",
    );
}

#[test]
fn test_unit_from_empty_seq_without_len() {
    assert_de_tokens_error::<()>(
        &[Token::Seq { len: None }, Token::SeqEnd],
        "invalid type: sequence, expected unit",
    );
}

#[test]
fn test_unit_from_tuple_struct() {
    assert_de_tokens_error::<()>(
        &[
            Token::TupleStruct {
                name: "Anything",
                len: 0,
            },
            Token::TupleStructEnd,
        ],
        "invalid type: sequence, expected unit",
    );
}

#[test]
fn test_string_from_unit() {
    assert_de_tokens_error::<String>(
        &[Token::Unit],
        "invalid type: unit value, expected a string",
    );
}

#[test]
fn test_btreeset_from_unit() {
    assert_de_tokens_error::<BTreeSet<isize>>(
        &[Token::Unit],
        "invalid type: unit value, expected a sequence",
    );
}

#[test]
fn test_btreeset_from_unit_struct() {
    assert_de_tokens_error::<BTreeSet<isize>>(
        &[Token::UnitStruct { name: "Anything" }],
        "invalid type: unit value, expected a sequence",
    );
}

#[test]
fn test_hashset_from_unit() {
    assert_de_tokens_error::<HashSet<isize>>(
        &[Token::Unit],
        "invalid type: unit value, expected a sequence",
    );
}

#[test]
fn test_hashset_from_unit_struct() {
    assert_de_tokens_error::<HashSet<isize>>(
        &[Token::UnitStruct { name: "Anything" }],
        "invalid type: unit value, expected a sequence",
    );
}

#[test]
fn test_vec_from_unit() {
    assert_de_tokens_error::<Vec<isize>>(
        &[Token::Unit],
        "invalid type: unit value, expected a sequence",
    );
}

#[test]
fn test_vec_from_unit_struct() {
    assert_de_tokens_error::<Vec<isize>>(
        &[Token::UnitStruct { name: "Anything" }],
        "invalid type: unit value, expected a sequence",
    );
}

#[test]
fn test_zero_array_from_unit() {
    assert_de_tokens_error::<[isize; 0]>(
        &[Token::Unit],
        "invalid type: unit value, expected an empty array",
    );
}

#[test]
fn test_zero_array_from_unit_struct() {
    assert_de_tokens_error::<[isize; 0]>(
        &[Token::UnitStruct { name: "Anything" }],
        "invalid type: unit value, expected an empty array",
    );
}

#[test]
fn test_btreemap_from_unit() {
    assert_de_tokens_error::<BTreeMap<isize, isize>>(
        &[Token::Unit],
        "invalid type: unit value, expected a map",
    );
}

#[test]
fn test_btreemap_from_unit_struct() {
    assert_de_tokens_error::<BTreeMap<isize, isize>>(
        &[Token::UnitStruct { name: "Anything" }],
        "invalid type: unit value, expected a map",
    );
}

#[test]
fn test_hashmap_from_unit() {
    assert_de_tokens_error::<HashMap<isize, isize>>(
        &[Token::Unit],
        "invalid type: unit value, expected a map",
    );
}

#[test]
fn test_hashmap_from_unit_struct() {
    assert_de_tokens_error::<HashMap<isize, isize>>(
        &[Token::UnitStruct { name: "Anything" }],
        "invalid type: unit value, expected a map",
    );
}

#[test]
fn test_bool_from_string() {
    assert_de_tokens_error::<bool>(
        &[Token::Str("false")],
        "invalid type: string \"false\", expected a boolean",
    );
}

#[test]
fn test_number_from_string() {
    assert_de_tokens_error::<isize>(
        &[Token::Str("1")],
        "invalid type: string \"1\", expected isize",
    );
}

#[test]
fn test_integer_from_float() {
    assert_de_tokens_error::<isize>(
        &[Token::F32(0.0)],
        "invalid type: floating point `0.0`, expected isize",
    );
}

#[test]
fn test_nan_no_decimal_point() {
    assert_de_tokens_error::<isize>(
        &[Token::F32(f32::NAN)],
        "invalid type: floating point `NaN`, expected isize",
    );
}

#[test]
fn test_unit_struct_from_seq() {
    assert_de_tokens_error::<UnitStruct>(
        &[Token::Seq { len: Some(0) }, Token::SeqEnd],
        "invalid type: sequence, expected unit struct UnitStruct",
    );
}

#[test]
fn test_wrapping_overflow() {
    assert_de_tokens_error::<Wrapping<u16>>(
        &[Token::U32(65_536)],
        "invalid value: integer `65536`, expected u16",
    );
}

#[test]
fn test_duration_overflow_seq() {
    assert_de_tokens_error::<Duration>(
        &[
            Token::Seq { len: Some(2) },
            Token::U64(u64::MAX),
            Token::U32(1_000_000_000),
            Token::SeqEnd,
        ],
        "overflow deserializing Duration",
    );
}

#[test]
fn test_duration_overflow_struct() {
    assert_de_tokens_error::<Duration>(
        &[
            Token::Struct {
                name: "Duration",
                len: 2,
            },
            Token::Str("secs"),
            Token::U64(u64::MAX),
            Token::Str("nanos"),
            Token::U32(1_000_000_000),
            Token::StructEnd,
        ],
        "overflow deserializing Duration",
    );
}

#[test]
fn test_systemtime_overflow_seq() {
    assert_de_tokens_error::<SystemTime>(
        &[
            Token::Seq { len: Some(2) },
            Token::U64(u64::MAX),
            Token::U32(1_000_000_000),
            Token::SeqEnd,
        ],
        "overflow deserializing SystemTime epoch offset",
    );
}

#[test]
fn test_systemtime_overflow_struct() {
    assert_de_tokens_error::<SystemTime>(
        &[
            Token::Struct {
                name: "SystemTime",
                len: 2,
            },
            Token::Str("secs_since_epoch"),
            Token::U64(u64::MAX),
            Token::Str("nanos_since_epoch"),
            Token::U32(1_000_000_000),
            Token::StructEnd,
        ],
        "overflow deserializing SystemTime epoch offset",
    );
}

#[test]
fn test_systemtime_overflow() {
    assert_de_tokens_error::<SystemTime>(
        &[
            Token::Seq { len: Some(2) },
            Token::U64(u64::MAX),
            Token::U32(0),
            Token::SeqEnd,
        ],
        "overflow deserializing SystemTime",
    );
}

#[test]
fn test_cstr_internal_null() {
    assert_de_tokens_error::<Box<CStr>>(
        &[Token::Bytes(b"a\0c")],
        "nul byte found in provided data at position: 1",
    );
}

#[test]
fn test_cstr_internal_null_end() {
    assert_de_tokens_error::<Box<CStr>>(
        &[Token::Bytes(b"ac\0")],
        "nul byte found in provided data at position: 2",
    );
}

#[cfg(feature = "unstable")]
#[test]
fn test_never_type() {
    assert_de_tokens_error::<!>(&[], "cannot deserialize `!`");

    assert_de_tokens_error::<Result<u8, !>>(
        &[Token::NewtypeVariant {
            name: "Result",
            variant: "Err",
        }],
        "cannot deserialize `!`",
    );
}


import MagicString from 'magic-string'
import type { Plugin } from '../plugin'
import type { ResolvedConfig } from '../config'
import { createFilter } from '../utils'
import { cleanUrl } from '../../shared/utils'

/**
 * This plugin supports `esbuild.banner` and `esbuild.footer` options.
 * esbuild supported these options and Vite exposed them.
 * But this should be done by plugin with transform hook.
 * This plugin makes these options work in rolldown-vite as a backward compat for now.
 */
export function esbuildBannerFooterCompatPlugin(
  config: ResolvedConfig,
): Plugin | undefined {
  const options = config.esbuild
  if (!options) return

  const { include, exclude, banner, footer } = options
  if (!banner && !footer) return

  const filter = createFilter(include || /\.(m?ts|[jt]sx)$/, exclude || /\.js$/)

  return {
    name: 'vite:esbuild-banner-footer-compat',
    transform(code, id) {
      if (filter(id) || filter(cleanUrl(id))) {
        const needsSourcemap =
          this.environment.mode === 'dev' ||
          (this.environment.mode === 'build' &&
            this.environment.config.build.sourcemap)
        if (!needsSourcemap) {
          if (banner) {
            code = `${banner}\n${code}`
          }
          if (footer) {
            code = `${code}\n${footer}`
          }
          return code
        }

        let s: MagicString | undefined
        const str = () => s || (s = new MagicString(code))

        if (banner) {
          str().prepend(`${banner}\n`)
        }
        if (footer) {
          str().append(`${footer}\n`)
        }

        if (s) {
          return {
            code: s.toString(),
            map: s.generateMap({ hires: 'boundary' }),
          }
        }
      }
    },
  }
}


<link rel="stylesheet" href="./linked.css" />

Lightning CSS

<link>: This should be blue

@import in <link>: This should be red

import from js: This should be green

    @import in import from js: This should be purple

    External CSS:

CSS modules: this should be turquoise

Imported CSS module:

Imported compose/from CSS module:

    CSS modules composes path resolving: this should be turquoise

Inline CSS module:

External URL

Assets relative to nested CSS

    CSS background (aliased)

    CSS background (pre inlined SVG)


import { expect, test } from 'vitest'
import {
  browserLogs,
  findAssetFile,
  getColor,
  isBuild,
  isBundled,
  isBundledDev,
  page,
  serverLogs,
} from '~utils'

test('should load literal dynamic import', async () => {
  await page.click('.baz')
  await expect.poll(() => page.textContent('.view')).toMatch('Baz view')
})

// bundled dev: the `@vite-ignore` import asks for /views/qux.js when clicked.
// That file is in the project root but not in the bundle.
// Bundled dev serves only the bundle, so the request fails.
// This is a real gap that should be fixed, not expected behavior.
// Tracked in vitejs/vite#23028
test.skipIf(isBundledDev)(
  'should load full dynamic import from public',
  async () => {
    await page.click('.qux')
    await expect.poll(() => page.textContent('.view')).toMatch('Qux view')
    // No warning should be logged as we are using @vite-ignore
    expect(
      serverLogs.some((log) => log.includes('cannot be analyzed by vite')),
    ).toBe(false)
  },
)

test('should load data URL of `blob:`', async () => {
  await page.click('.issue-2658-1')
  await expect.poll(() => page.textContent('.view')).toMatch('blob')
})

test('should load data URL of `data:`', async () => {
  await page.click('.issue-2658-2')
  await expect.poll(() => page.textContent('.view')).toMatch('data')
})

test('should have same reference on static and dynamic js import, .mxd', async () => {
  await page.click('.mxd')
  await expect.poll(() => page.textContent('.view')).toMatch('true')
})

// in this case, it is not possible to detect the correct module
// bundled dev: the `@vite-ignore` URL points at the source file
// ../files/mxd.js. That file is not in the bundle, so it is not served.
test.skipIf(isBundledDev)(
  'should have same reference on static and dynamic js import, .mxd2',
  async () => {
    await page.click('.mxd2')
    await expect.poll(() => page.textContent('.view')).toMatch('false')
  },
)

test('should have same reference on static and dynamic js import, .mxdjson', async () => {
  await page.click('.mxdjson')
  await expect.poll(() => page.textContent('.view')).toMatch('true')
})

// since this test has a timeout, it should be put last so that it
// does not bleed on the last
test('should load dynamic import with vars', async () => {
  await page.click('.foo')
  await expect.poll(() => page.textContent('.view')).toMatch('Foo view')

  await page.click('.bar')
  await expect.poll(() => page.textContent('.view')).toMatch('Bar view')
})

// dynamic import css
test('should load dynamic import with css', async () => {
  await page.click('.css')
  await expect.poll(() => getColor('.view')).toBe('red')
})

test('should load dynamic import with vars', async () => {
  await expect
    .poll(() => page.textContent('.dynamic-import-with-vars'))
    .toMatch('hello')
})

test('should load dynamic import with vars ignored', async () => {
  await expect
    .poll(() => page.textContent('.dynamic-import-with-vars-ignored'))
    .toMatch('hello')
  // No warning should be logged as we are using @vite-ignore
  expect(
    serverLogs.some((log) =>
      log.includes('"https" has been externalized for browser compatibility'),
    ),
  ).toBe(false)
})

test('should load dynamic import with double slash ignored', async () => {
  await expect
    .poll(() => page.textContent('.dynamic-import-with-double-slash-ignored'))
    .toMatch('hello')
})

test('should load dynamic import with vars multiline', async () => {
  await expect
    .poll(() => page.textContent('.dynamic-import-with-vars-multiline'))
    .toMatch('hello')
})

test('should load dynamic import with vars alias', async () => {
  await expect
    .poll(() => page.textContent('.dynamic-import-with-vars-alias'))
    .toMatch('hi')
})

test('should load dynamic import with vars raw', async () => {
  await expect
    .poll(() => page.textContent('.dynamic-import-with-vars-raw'))
    .toMatch('export function hello()')
})

test('should load dynamic import with vars url', async () => {
  await expect
    .poll(() => page.textContent('.dynamic-import-with-vars-url'))
    .toMatch(isBundled ? 'data:text/javascript' : '/alias/url.js')
})

// bundled dev: workers created through the dynamic-import-vars glob aren't
// bundled as worker entries yet
test.skipIf(isBundledDev)(
  'should load dynamic import with vars worker',
  async () => {
    await expect
      .poll(() => page.textContent('.dynamic-import-with-vars-worker'))
      .toMatch('load worker')
  },
)

test('should load dynamic import with css in package', async () => {
  await page.click('.pkg-css')
  await expect.poll(() => getColor('.pkg-css')).toBe('blue')
})

test('should work with load ../ and itself directory', async () => {
  await expect
    .poll(() => page.textContent('.dynamic-import-self'))
    .toMatch('dynamic-import-self-content')
})

test('should work with load ../ and contain itself directory', async () => {
  await expect
    .poll(() => page.textContent('.dynamic-import-nested-self'))
    .toMatch('dynamic-import-nested-self-content')
})

// #22700: nested `import('a').then(() => import('b'))` where `a` has a CSS
// side-effect dep — the outer import's CSS must still be loaded in build output
test('should load css of nested dynamic import', async () => {
  await expect
    .poll(() => page.textContent('.then-css-outer'))
    .toMatch('then-css-outer')
  await expect.poll(() => getColor('.then-css-outer')).toBe('red')
  await expect
    .poll(() => page.textContent('.then-css-inner'))
    .toMatch('then-css-inner')
  await expect.poll(() => getColor('.then-css-inner')).toBe('green')
})

test('should handle object rest destructuring of a dynamic import', async () => {
  await expect
    .poll(() => page.textContent('.dynamic-import-rest'))
    .toMatch('a rest-b rest-c')
})

test('should work a load path that contains parentheses.', async () => {
  await expect
    .poll(() =>
      page.textContent('.dynamic-import-with-vars-contains-parenthesis'),
    )
    .toMatch('dynamic-import-with-vars-contains-parenthesis')
})

test.runIf(isBuild)(
  'should rollup warn when static and dynamic import a module in same chunk',
  // NOTE: this is a warning related to rollup's chunking behavior
  { skip: true },
  async () => {
    const log = serverLogs.join('\n')
    expect(log).toContain(
      'dynamic import will not move module into another chunk',
    )
    expect(log).toMatch(
      /\(!\).*\/dynamic-import\/files\/mxd\.js is dynamically imported by/,
    )
    expect(log).toMatch(
      /\(!\).*\/dynamic-import\/files\/mxd\.json is dynamically imported by/,
    )
    expect(log).not.toMatch(
      /\(!\).*\/dynamic-import\/nested\/shared\.js is dynamically imported by/,
    )
  },
)

test('dynamic import treeshaken log', async () => {
  const log = browserLogs.join('\n')
  expect(log).toContain('treeshaken foo')
  expect(log).toContain('treeshaken bar')
  expect(log).toContain('treeshaken baz1')
  expect(log).toContain('treeshaken baz2')
  expect(log).toContain('treeshaken baz3')
  expect(log).toContain('treeshaken baz4')
  expect(log).toContain('treeshaken baz5')
  expect(log).toContain('treeshaken baz6')
  expect(log).toContain('treeshaken default')

  expect(log).not.toContain('treeshaken removed')
})

test('dynamic import syntax parsing', async () => {
  const log = browserLogs.join('\n')
  expect(log).toContain('treeshaken syntax foo')
  expect(log).toContain('treeshaken syntax default')
})

test.runIf(isBuild)('dynamic import treeshaken file', async () => {
  expect(findAssetFile(/treeshaken.+\.js$/)).not.toContain('treeshaken removed')
})

test.runIf(isBuild)('should not preload for non-analyzable urls', () => {
  const js = findAssetFile(/index-[-\w]{8}\.js$/)
  // should match e.g. await import(e.jss);o(".view",p===i)
  expect(js).to.match(/\.jss\);/)
})


"""
requests._internal_utils
~~~~~~~~~~~~~~

Provides utility functions that are consumed internally by Requests
which depend on extremely few external helpers (such as compat)
"""

import re

from .compat import builtin_str

_VALID_HEADER_NAME_RE_BYTE = re.compile(rb"^[^:\s][^:\r\n]*\Z")
_VALID_HEADER_NAME_RE_STR = re.compile(r"^[^:\s][^:\r\n]*\Z")
_VALID_HEADER_VALUE_RE_BYTE = re.compile(rb"^\S[^\r\n]*\Z|^\Z")
_VALID_HEADER_VALUE_RE_STR = re.compile(r"^\S[^\r\n]*\Z|^\Z")

_HEADER_VALIDATORS_STR = (_VALID_HEADER_NAME_RE_STR, _VALID_HEADER_VALUE_RE_STR)
_HEADER_VALIDATORS_BYTE = (_VALID_HEADER_NAME_RE_BYTE, _VALID_HEADER_VALUE_RE_BYTE)
HEADER_VALIDATORS = {
    bytes: _HEADER_VALIDATORS_BYTE,
    str: _HEADER_VALIDATORS_STR,
}

def to_native_string(string: str | bytes, encoding: str = "ascii") -> str:
    """Given a string object, regardless of type, returns a representation of
    that string in the native string type, encoding and decoding where
    necessary. This assumes ASCII unless told otherwise.
    """
    if isinstance(string, builtin_str):
        out = string
    else:
        out = string.decode(encoding)

    return out

def unicode_is_ascii(u_string: str) -> bool:
    """Determine if unicode string only contains ASCII characters.

    :param str u_string: unicode string to check. Must be unicode
        and not Python 2 `str`.
    :rtype: bool
    """
    assert isinstance(u_string, str)
    try:
        u_string.encode("ascii")
        return True
    except UnicodeEncodeError:
        return False


import fs from 'node:fs'
import path from 'node:path'
import { describe, expect, test } from 'vitest'
import { isBuild, page, testDir } from '~utils'

test('normal', async () => {
  await expect.poll(() => page.textContent('.pong')).toMatch('pong')
  await expect
    .poll(() => page.textContent('.mode'))
    .toMatch(process.env.NODE_ENV)
  await expect
    .poll(() => page.textContent('.bundle-with-plugin'))
    .toMatch('worker bundle with plugin success!')
  await expect
    .poll(() => page.textContent('.asset-url'))
    .toMatch(isBuild ? '/worker-assets/worker_asset-vite' : '/vite.svg')
})

test('named', async () => {
  await expect
    .poll(() => page.textContent('.pong-named'))
    .toMatch('namedWorker')
})

test('TS output', async () => {
  await expect.poll(() => page.textContent('.pong-ts-output')).toMatch('pong')
})

// TODO: inline worker should inline assets
test.skip('inlined', async () => {
  await expect.poll(() => page.textContent('.pong-inline')).toMatch('pong')
})

test('shared worker', async () => {
  await expect.poll(() => page.textContent('.tick-count')).toMatch('pong')
})

test('named shared worker', async () => {
  await expect.poll(() => page.textContent('.tick-count-named')).toMatch('pong')
})

test('inline shared worker', async () => {
  await expect
    .poll(() => page.textContent('.pong-shared-inline'))
    .toMatch('pong')
})

test('worker emitted and import.meta.url in nested worker (serve)', async () => {
  await expect
    .poll(() => page.textContent('.nested-worker'))
    .toMatch('worker-nested-worker')
  await expect
    .poll(() => page.textContent('.nested-worker-module'))
    .toMatch('sub-worker')
  await expect
    .poll(() => page.textContent('.nested-worker-constructor'))
    .toMatch('"type":"constructor"')
})

describe.runIf(isBuild)('build', () => {
  // assert correct files
  test('inlined code generation', () => {
    const chunksDir = path.resolve(testDir, 'dist/relative-base/chunks')
    const files = fs.readdirSync(chunksDir)
    const index = files.find((f) => f.includes('main-module'))
    const content = fs.readFileSync(path.resolve(chunksDir, index), 'utf-8')
    const workerEntriesDir = path.resolve(
      testDir,
      'dist/relative-base/worker-entries',
    )
    const workerFiles = fs.readdirSync(workerEntriesDir)
    const worker = workerFiles.find((f) => f.includes('worker_entry-my-worker'))
    const workerContent = fs.readFileSync(
      path.resolve(workerEntriesDir, worker),
      'utf-8',
    )

    // worker should have all imports resolved and no exports
    expect(workerContent).not.toMatch(/import\s*["(]/)
    expect(workerContent).not.toMatch(/\bexport\b/)
    // chunk
    expect(content).toMatch('new Worker(``+new URL(`../worker-entries/')
    expect(content).toMatch('new SharedWorker(``+new URL(`../worker-entries/')
    // inlined
    expect(content).toMatch(`(self.URL||self.webkitURL).createObjectURL`)
    expect(content).toMatch(`self.Blob`)
  })

  test('worker emitted and import.meta.url in nested worker (build)', async () => {
    await expect
      .poll(() => page.textContent('.nested-worker-module'))
      .toMatch('"type":"module"')
    await expect
      .poll(() => page.textContent('.nested-worker-constructor'))
      .toMatch('"type":"constructor"')
  })
})

test('module worker', async () => {
  await expect
    .poll(() => page.textContent('.shared-worker-import-meta-url'))
    .toMatch('A string')
})

test('classic worker', async () => {
  await expect
    .poll(() => page.textContent('.classic-worker'))
    .toMatch('A classic')
  if (!isBuild) {
    await expect
      .poll(() => page.textContent('.classic-worker-import'))
      .toMatch('[success] classic-esm')
  }
  await expect
    .poll(() => page.textContent('.classic-shared-worker'))
    .toMatch('A classic')
})

test.runIf(isBuild)('emit chunk', async () => {
  await expect
    .poll(() => page.textContent('.emit-chunk-worker'))
    .toMatch(
      '["A string",{"type":"emit-chunk-sub-worker","data":"A string"},{"type":"module-and-worker:worker","data":"A string"},{"type":"module-and-worker:module","data":"module and worker"},{"type":"emit-chunk-sub-worker","data":{"module":"module and worker","msg1":"module1","msg2":"module2","msg3":"module3"}}]',
    )
  await expect
    .poll(() => page.textContent('.emit-chunk-dynamic-import-worker'))
    .toMatch('"A stringmodule1./"')
})

test('import.meta.glob in worker', async () => {
  await expect
    .poll(() => page.textContent('.importMetaGlob-worker'))
    .toMatch('["')
})

test('import.meta.glob with eager in worker', async () => {
  await expect
    .poll(() => page.textContent('.importMetaGlobEager-worker'))
    .toMatch('["')
})

test('self reference worker', async () => {
  await expect
    .poll(() => page.textContent('.self-reference-worker'))
    .toBe('pong: main\npong: nested\n')
})

test('self reference url worker', async () => {
  await expect
    .poll(() => page.textContent('.self-reference-url-worker'))
    .toBe('pong: main\npong: nested\n')
})


# JSON_SKIP_UNSUPPORTED_COMPILER_CHECK

```cpp
#define JSON_SKIP_UNSUPPORTED_COMPILER_CHECK
```

When defined, the library will not create a compile error when a known unsupported compiler is detected. This allows
using the library with compilers that do not fully support C++11 and may only work if unsupported features are not used.

## Default definition

By default, the macro is not defined.

```cpp
#undef JSON_SKIP_UNSUPPORTED_COMPILER_CHECK
```

## Examples

??? example

    The code below switches off the check whether the compiler is supported.

    ```cpp
    #define JSON_SKIP_UNSUPPORTED_COMPILER_CHECK 1
    #include <nlohmann/json.hpp>

    ...
    ```

## Version history

Added in version 3.2.0.


import { type Plugin, defineConfig } from 'vite'

export default defineConfig({
  experimental: {
    bundledDev: true,
  },
  build: {
    // emit assets as files instead of inlining, for the new-asset HMR test
    assetsInlineLimit: 0,
  },
  plugins: [waitBundleCompleteUntilAccess(), delayTransformComment()],
})

function waitBundleCompleteUntilAccess(): Plugin {
  let resolvers: PromiseWithResolvers<void>

  return {
    name: 'wait-bundle-complete-until-access',
    apply: 'serve',
    configureServer(server) {
      let accessCount = 0
      resolvers = promiseWithResolvers()

      server.middlewares.use((_req, _res, next) => {
        accessCount++
        if (accessCount === 1) {
          resolvers.resolve()
        }
        next()
      })
    },
    async generateBundle() {
      await resolvers.promise
      await new Promise<void>((resolve) => setTimeout(resolve, 300))
    },
  }
}

function delayTransformComment(): Plugin {
  return {
    name: 'delay-transform-comment',
    async transform(code) {
      if (code.includes('// @delay-transform')) {
        await new Promise<void>((resolve) => setTimeout(resolve, 300))
      }
    },
  }
}

interface PromiseWithResolvers<T> {
  promise: Promise<T>
  resolve: (value: T | PromiseLike<T>) => void
  reject: (reason?: any) => void
}
function promiseWithResolvers<T>(): PromiseWithResolvers<T> {
  let resolve: any
  let reject: any
  const promise = new Promise<T>((_resolve, _reject) => {
    resolve = _resolve
    reject = _reject
  })
  return { promise, resolve, reject }
}


This test aims to check for a particular type of circular dependency that causes tricky deadlocks, **deadlocks with forked imports stack**

```
A -> B means: B is imported by A and B has A in its stack
A ... B means: A is waiting for B to ssrLoadModule()

H -> X ... Y
H -> X -> Y ... B
H -> A ... B
H -> A -> B ... X
```

### Forked deadlock description:

```
[X] is waiting for [Y] to resolve
 ↑                  ↳ is waiting for [A] to resolve
 │                                    ↳ is waiting for [B] to resolve
 │                                                      ↳ is waiting for [X] to resolve
 └────────────────────────────────────────────────────────────────────────┘
```

This may seems a traditional deadlock, but the thing that makes this special is the import stack of each module:

```
[X] stack:
	[H]
```

```
[Y] stack:
	[X]
	[H]
```

```
[A] stack:
	[H]
```

```
[B] stack:
	[A]
	[H]
```

Even if `[X]` is imported by `[B]`, `[B]` is not in `[X]`'s stack because it's imported by `[H]` in first place then it's stack is only composed by `[H]`. `[H]` **forks** the imports **stack** and this makes it hard to be found.

### Fix description

Vite, when imports `[X]`, should check whether `[X]` is already pending and if it is, it must check that, when it was imported in first place, the stack of `[X]` doesn't have any module in common with the current module; in this case `[B]` has the module `[H]` is common with `[X]` and i can assume that a deadlock is going to happen.


# Features

At the very basic level, developing using Vite is not that different from using a static file server. However, Vite provides many enhancements over native ESM imports to support various features that are typically seen in bundler-based setups.

## npm Dependency Resolving and Pre-Bundling

Native ES imports do not support bare module imports like the following:

```js
import { someMethod } from 'my-dep'
```

The above import will throw an error in the browser. Vite will detect such bare module imports in all served source files and perform the following:

1. [Pre-bundle](./dep-pre-bundling) them to improve page loading speed and convert CommonJS / UMD modules to ESM. The pre-bundling step is performed with [Rolldown](https://rolldown.rs/) and makes Vite's cold start time significantly faster than any JavaScript-based bundler.

2. Rewrite the imports to valid URLs like `/node_modules/.vite/deps/my-dep.js?v=f3sf2ebd` so that the browser can import them properly.

**Dependencies are Strongly Cached**

Vite caches dependency requests via HTTP headers, so if you wish to locally edit/debug a dependency, follow the steps [here](./dep-pre-bundling#browser-cache).

## Hot Module Replacement

Vite provides an [HMR API](./api-hmr) over native ESM. Frameworks with HMR capabilities can leverage the API to provide instant, precise updates without reloading the page or blowing away application state. Vite provides first-party HMR integrations for [Vue Single File Components](https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue) and [React Fast Refresh](https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react). There are also official integrations for Preact via [@prefresh/vite](https://github.com/JoviDeCroock/prefresh/tree/main/packages/vite).

Note you don't need to manually set these up - when you [create an app via `create-vite`](./), the selected templates would have these pre-configured for you already.

## TypeScript

Vite supports importing `.ts` files out of the box.

### Transpile Only

Note that Vite only performs transpilation on `.ts` files and does **NOT** perform type checking. It assumes type checking is taken care of by your IDE and build process.

The reason Vite does not perform type checking as part of the transform process is because the two jobs work fundamentally differently. Transpilation can work on a per-file basis and aligns perfectly with Vite's on-demand compile model. In comparison, type checking requires knowledge of the entire module graph. Shoe-horning type checking into Vite's transform pipeline will inevitably compromise Vite's speed benefits.

Vite's job is to get your source modules into a form that can run in the browser as fast as possible. To that end, we recommend separating static analysis checks from Vite's transform pipeline. This principle applies to other static analysis checks such as ESLint.

- For production builds, you can run `tsc --noEmit` in addition to Vite's build command.

- During development, if you need more than IDE hints, we recommend running `tsc --noEmit --watch` in a separate process, or use [vite-plugin-checker](https://github.com/fi3ework/vite-plugin-checker) if you prefer having type errors directly reported in the browser.

Vite uses [Oxc Transformer](https://oxc.rs/docs/guide/usage/transformer.html) to transpile TypeScript into JavaScript which is faster than vanilla `tsc`, and HMR updates can reflect in the browser in under 50ms.

Use the [Type-Only Imports and Export](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export) syntax to avoid potential problems like type-only imports being incorrectly bundled, for example:

```ts
import type { T } from 'only/types'
export type { T }
```

### TypeScript Compiler Options

Vite respects some of the options in `tsconfig.json` and sets the corresponding Oxc Transformer options. For each file, Vite uses the closest parent `tsconfig.json` that matches the file, or a config referenced by its [`references`](https://www.typescriptlang.org/tsconfig/#references) field that matches the file. Vite treats a config as matching the file when the file satisfies the config's [`files`](https://www.typescriptlang.org/tsconfig/#files), [`include`](https://www.typescriptlang.org/tsconfig/#include), and [`exclude`](https://www.typescriptlang.org/tsconfig/#exclude) fields.

When the options are set in both the Vite config and the `tsconfig.json`, the value in the Vite config takes precedence.

Some configuration fields under `compilerOptions` in `tsconfig.json` require special attention.

#### `isolatedModules`

- [TypeScript documentation](https://www.typescriptlang.org/tsconfig#isolatedModules)

Should be set to `true`.

It is because Oxc transformer only performs transpilation without type information, it doesn't support certain features like const enum and implicit type-only imports.

You must set `"isolatedModules": true` in your `tsconfig.json` under `compilerOptions`, so that TS will warn you against the features that do not work with isolated transpilation.

If a dependency doesn't work well with `"isolatedModules": true`, you can use `"skipLibCheck": true` to temporarily suppress the errors until it is fixed upstream.

#### `useDefineForClassFields`

- [TypeScript documentation](https://www.typescriptlang.org/tsconfig#useDefineForClassFields)

The default value will be `true` if the TypeScript target is `ES2022` or newer including `ESNext`. It is consistent with the [behavior of TypeScript 4.3.2+](https://github.com/microsoft/TypeScript/pull/42663).
Other TypeScript targets will default to `false`.

`true` is the standard ECMAScript runtime behavior.

If you are using a library that heavily relies on class fields, please be careful about the library's intended usage of it.
While most libraries expect `"useDefineForClassFields": true`, you can explicitly set `useDefineForClassFields` to `false` if your library doesn't support it.

#### `target`

- [TypeScript documentation](https://www.typescriptlang.org/tsconfig#target)

Vite ignores the `target` value in the `tsconfig.json`, following the same behavior as [esbuild](https://esbuild.github.io/).

To specify the target in dev, the [`oxc.target`](/config/shared-options.html#oxc) option can be used, which defaults to `esnext` for minimal transpilation. In builds, the [`build.target`](/config/build-options.html#build-target) option takes higher priority over `oxc.target` and can also be set if needed.

#### `emitDecoratorMetadata`

- [TypeScript documentation](https://www.typescriptlang.org/tsconfig#emitDecoratorMetadata)

This option is only partially supported. Full support requires type inference by the TypeScript compiler, which is not supported. See [Oxc Transformer's documentation](https://oxc.rs/docs/guide/usage/transformer/typescript.html#decorators) for details.

#### `paths`

- [TypeScript documentation](https://www.typescriptlang.org/tsconfig/#paths)

[`resolve.tsconfigPaths: true`](/config/shared-options.md#resolve-tsconfigpaths) can be specified to tell Vite to use the `paths` option in `tsconfig.json` to resolve imports.

Note that this feature has a performance cost and is [discouraged by the TypeScript team to use this option to change the behavior of the external tools](https://www.typescriptlang.org/tsconfig/#paths:~:text=Note%20that%20this%20feature%20does%20not%20change%20how%20import%20paths%20are%20emitted%20by%20tsc%2C%20so%20paths%20should%20only%20be%20used%20to%20inform%20TypeScript%20that%20another%20tool%20has%20this%20mapping%20and%20will%20use%20it%20at%20runtime%20or%20when%20bundling.).

#### Other Compiler Options Affecting the Build Result

- [`extends`](https://www.typescriptlang.org/tsconfig#extends)
- [`importsNotUsedAsValues`](https://www.typescriptlang.org/tsconfig#importsNotUsedAsValues)
- [`preserveValueImports`](https://www.typescriptlang.org/tsconfig#preserveValueImports)
- [`verbatimModuleSyntax`](https://www.typescriptlang.org/tsconfig#verbatimModuleSyntax)
- [`jsx`](https://www.typescriptlang.org/tsconfig#jsx)
- [`jsxFactory`](https://www.typescriptlang.org/tsconfig#jsxFactory)
- [`jsxFragmentFactory`](https://www.typescriptlang.org/tsconfig#jsxFragmentFactory)
- [`jsxImportSource`](https://www.typescriptlang.org/tsconfig#jsxImportSource)
- [`experimentalDecorators`](https://www.typescriptlang.org/tsconfig#experimentalDecorators)

::: tip `skipLibCheck`
Vite starter templates have `"skipLibCheck": true` by default to avoid typechecking dependencies, as they may choose to only support specific versions and configurations of TypeScript. You can learn more at [vuejs/vue-cli#5688](https://github.com/vuejs/vue-cli/pull/5688).
:::

### Client Types

Vite's default types are for its Node.js API. To shim the environment of client-side code in a Vite application, you can add `vite/client` to `compilerOptions.types` inside `tsconfig.json`:

```json [tsconfig.json]
{
  "compilerOptions": {
    "types": ["vite/client", "some-other-global-lib"]
  }
}
```

Note that if [`compilerOptions.types`](https://www.typescriptlang.org/tsconfig#types) is specified, only these packages will be included in the global scope (instead of all visible ”@types” packages). This is recommended since TS 5.9.

::: details Using triple-slash directive

Alternatively, you can add a `d.ts` declaration file:

```typescript [vite-env.d.ts]
/// <reference types="vite/client" />
```

:::

`vite/client` provides the following type shims:

- Asset imports (e.g. importing an `.svg` file)
- Types for the Vite-injected [constants](./env-and-mode#env-variables) on `import.meta.env`
- Types for the [HMR API](./api-hmr) on `import.meta.hot`

::: tip
To override the default typing, add a type definition file that contains your typings. Then, add the type reference before `vite/client`.

For example, to make the default import of `*.svg` a React component:

- `vite-env-override.d.ts` (the file that contains your typings):
  ```ts
  declare module '*.svg' {
    const content: React.FC<React.SVGProps<SVGElement>>
    export default content
  }
  ```
- If you are using `compilerOptions.types`, ensure the file is included in `tsconfig.json`:
  ```json [tsconfig.json]
  {
    "include": ["src", "./vite-env-override.d.ts"]
  }
  ```
- If you are using triple-slash directives, update the file containing the reference to `vite/client` (normally `vite-env.d.ts`):
  ```ts
  /// <reference types="./vite-env-override.d.ts" />
  /// <reference types="vite/client" />
  ```

:::

## HTML

HTML files stand [front-and-center](/guide/#index-html-and-project-root) of a Vite project, serving as the entry points for your application, making it simple to build single-page and [multi-page applications](/guide/build.html#multi-page-app).

Any HTML files in your project root can be directly accessed by its respective directory path:

- `<root>/index.html` -> `http://localhost:5173/`
- `<root>/about.html` -> `http://localhost:5173/about.html`
- `<root>/blog/index.html` -> `http://localhost:5173/blog/index.html`

Assets referenced by HTML elements such as `<script type="module" src>` and `<link href>` are processed and bundled as part of the app. The full list of supported elements is as below:

- `<audio src>`
- `<embed src>`
- `<img src>` and `<img srcset>`
- `<image href>` and `<image xlink:href>`
- `<input src>`
- `<link href>` and `<link imagesrcset>`
- `<object data>`
- `<script type="module" src>`
- `<source src>` and `<source srcset>`
- `<track src>`
- `<use href>` and `<use xlink:href>`
- `<video src>` and `<video poster>`
- `<meta content>`
  - Only if `name` attribute matches `msapplication-tileimage`, `msapplication-square70x70logo`, `msapplication-square150x150logo`, `msapplication-wide310x150logo`, `msapplication-square310x310logo`, `msapplication-config`, or `twitter:image`
  - Or only if `property` attribute matches `og:image`, `og:image:url`, `og:image:secure_url`, `og:audio`, `og:audio:secure_url`, `og:video`, or `og:video:secure_url`

```html {4-5,8-9}
<!doctype html>
<html>
  <head>
    <link rel="icon" href="/favicon.ico" />
    <link rel="stylesheet" href="/src/styles.css" />
  </head>
  <body>
    <img src="/src/images/logo.svg" alt="logo" />
    <script type="module" src="/src/main.js"></script>
  </body>
</html>
```

To opt-out of HTML processing on certain elements, you can add the `vite-ignore` attribute on the element, which can be useful when referencing external assets or CDN.

## Frameworks

All modern frameworks maintain integrations with Vite. Most framework plugins are maintained by each framework team, with the exception of the official Vue and React Vite plugins that are maintained in the vite org:

- Vue support via [@vitejs/plugin-vue](https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue)
- Vue JSX support via [@vitejs/plugin-vue-jsx](https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue-jsx)
- React support via [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react)
- React using SWC support via [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react-swc)
- [React Server Components (RSC)](https://react.dev/reference/rsc/server-components) support via [@vitejs/plugin-rsc](https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-rsc)

Check out the [Plugins Guide](/plugins/) for more information.

## JSX

`.jsx` and `.tsx` files are also supported out of the box. JSX transpilation is also handled via [Oxc Transformer](https://oxc.rs/docs/guide/usage/transformer.html).

Your framework of choice will already configure JSX out of the box (for example, Vue users should use the official [@vitejs/plugin-vue-jsx](https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue-jsx) plugin, which provides Vue 3 specific features including HMR, global component resolving, directives and slots).

If using JSX with your own framework, custom `jsxFactory` and `jsxFragment` can be configured using the [`oxc` option](/config/shared-options.md#oxc). For example, the Preact plugin would use:

```js twoslash [vite.config.js]
import { defineConfig } from 'vite'

export default defineConfig({
  oxc: {
    jsx: {
      importSource: 'preact',
    },
  },
})
```

More details in [Oxc Transformer docs](https://oxc.rs/docs/guide/usage/transformer/jsx.html).

You can inject the JSX helpers using `jsxInject` (which is a Vite-only option) to avoid manual imports:

```js twoslash [vite.config.js]
import { defineConfig } from 'vite'

export default defineConfig({
  oxc: {
    jsxInject: `import React from 'react'`,
  },
})
```

## CSS

Importing `.css` files will inject its content to the page via a `<style>` tag with HMR support.

### `@import` Inlining and Rebasing

Vite is pre-configured to support CSS `@import` inlining via `postcss-import`. Vite aliases are also respected for CSS `@import`. In addition, all CSS `url()` references, even if the imported files are in different directories, are always automatically rebased to ensure correctness.

`@import` aliases and URL rebasing are also supported for Sass and Less files (see [CSS Pre-processors](#css-pre-processors)).

### PostCSS

If the project contains valid PostCSS config (any format supported by [postcss-load-config](https://github.com/postcss/postcss-load-config), e.g. `postcss.config.js`), it will be automatically applied to all imported CSS.

Note that CSS minification will run after PostCSS and will use [`build.cssTarget`](/config/build-options.md#build-csstarget) option.

### CSS Modules

Any CSS file ending with `.module.css` is considered a [CSS modules file](https://github.com/css-modules/css-modules). Importing such a file will return the corresponding module object:

```css [example.module.css]
.red {
  color: red;
}
```

```js twoslash
import 'vite/client'
// ---cut---
import classes from './example.module.css'
document.getElementById('foo').className = classes.red
```

CSS modules behavior can be configured via the [`css.modules` option](/config/shared-options.md#css-modules).

If `css.modules.localsConvention` is set to enable camelCase locals (e.g. `localsConvention: 'camelCaseOnly'`), you can also use named imports:

```js twoslash
import 'vite/client'
// ---cut---
// .apply-color -> applyColor
import { applyColor } from './example.module.css'
document.getElementById('foo').className = applyColor
```

### CSS Pre-processors

Because Vite targets modern browsers only, it is recommended to use native CSS variables with PostCSS plugins that implement CSSWG drafts (e.g. [postcss-nesting](https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-nesting)) and author plain, future-standards-compliant CSS.

That said, Vite does provide built-in support for `.scss`, `.sass`, `.less`, `.styl` and `.stylus` files. There is no need to install Vite-specific plugins for them, but the corresponding pre-processor itself must be installed:

```bash
# .scss and .sass
npm add -D sass-embedded # or sass

# .less
npm add -D less

# .styl and .stylus
npm add -D stylus
```

If using Vue single file components, this also automatically enables `<style lang="sass">` et al.

Vite improves `@import` resolving for Sass and Less so that Vite aliases are also respected. In addition, relative `url()` references inside imported Sass/Less files that are in different directories from the root file are also automatically rebased to ensure correctness. Rebasing `url()` references that start with a variable or an interpolation is not supported due to its API constraints.

`@import` alias and url rebasing are not supported for Stylus due to its API constraints.

You can also use CSS modules combined with pre-processors by prepending `.module` to the file extension, for example `style.module.scss`.

### Disabling CSS injection into the page

The automatic injection of CSS contents can be turned off via the `?inline` query parameter. In this case, the processed CSS string is returned as the module's default export as usual, but the styles aren't injected to the page.

```js twoslash
import 'vite/client'
// ---cut---
import './foo.css' // will be injected into the page
import otherStyles from './bar.css?inline' // will not be injected
```

::: tip NOTE
Default and named imports from CSS files (e.g `import style from './foo.css'`) are removed since Vite 5. Use the `?inline` query instead.
:::

### Lightning CSS

Vite uses [Lightning CSS](https://lightningcss.dev/) to minify CSS in production builds by default. However, PostCSS is still used for other CSS processing.

There is experimental support for using Lightning CSS for CSS processing entirely. You can opt into it by adding [`css.transformer: 'lightningcss'`](../config/shared-options.md#css-transformer).

To configure it, you can pass Lightning CSS options to the [`css.lightningcss`](../config/shared-options.md#css-lightningcss) config option. To configure CSS Modules, you should use [`css.lightningcss.cssModules`](https://lightningcss.dev/css-modules.html) instead of [`css.modules`](../config/shared-options.md#css-modules) (which configures the way PostCSS handles CSS modules).

## Static Assets

<ScrimbaLink href="https://scrimba.com/intro-to-vite-c03p6pbbdq/~05pq?via=vite" title="Static Assets in Vite">Watch an interactive lesson on Scrimba</ScrimbaLink>

Importing a static asset will return the resolved public URL when it is served:

```js twoslash
import 'vite/client'
// ---cut---
import imgUrl from './img.png'
document.getElementById('hero-img').src = imgUrl
```

Special queries can modify how assets are loaded:

```js twoslash
import 'vite/client'
// ---cut---
// Explicitly load assets as URL (automatically inlined depending on the file size)
import assetAsURL from './asset.js?url'
```

```js twoslash
import 'vite/client'
// ---cut---
// Load assets as strings
import assetAsString from './shader.glsl?raw'
```

```js twoslash
import 'vite/client'
// ---cut---
// Load Web Workers
import Worker from './worker.js?worker'
```

```js twoslash
import 'vite/client'
// ---cut---
// Web Workers inlined as base64 strings at build time
import InlineWorker from './worker.js?worker&inline'
```

More details in [Static Asset Handling](./assets).

## JSON

JSON files can be directly imported - named imports are also supported:

```js twoslash
import 'vite/client'
// ---cut---
// import the entire object
import json from './example.json'
// import a root field as named exports - helps with tree-shaking!
import { field } from './example.json'
```

## Glob Import

Vite supports importing multiple modules from the file system via the special `import.meta.glob` function:

```js twoslash
import 'vite/client'
// ---cut---
const modules = import.meta.glob('./dir/*.js')
```

The above will be transformed into the following:

```js
// code produced by vite
const modules = {
  './dir/bar.js': () => import('./dir/bar.js'),
  './dir/foo.js': () => import('./dir/foo.js'),
}
```

You can then iterate over the keys of the `modules` object to access the corresponding modules:

```js
for (const path in modules) {
  modules[path]().then((mod) => {
    console.log(path, mod)
  })
}
```

Matched files are by default lazy-loaded via dynamic import and will be split into separate chunks during build. If you'd rather import all the modules directly (e.g. relying on side-effects in these modules to be applied first), you can pass `{ eager: true }` as the second argument:

```js twoslash
import 'vite/client'
// ---cut---
const modules = import.meta.glob('./dir/*.js', { eager: true })
```

The above will be transformed into the following:

```js
// code produced by vite
import * as __vite_glob_0_0 from './dir/bar.js'
import * as __vite_glob_0_1 from './dir/foo.js'
const modules = {
  './dir/bar.js': __vite_glob_0_0,
  './dir/foo.js': __vite_glob_0_1,
}
```

### Multiple Patterns

The first argument can be an array of globs, for example

```js twoslash
import 'vite/client'
// ---cut---
const modules = import.meta.glob(['./dir/*.js', './another/*.js'])
```

### Negative Patterns

Negative glob patterns are also supported (prefixed with `!`). To ignore some files from the result, you can add exclude glob patterns to the first argument:

```js twoslash
import 'vite/client'
// ---cut---
const modules = import.meta.glob(['./dir/*.js', '!**/bar.js'])
```

```js
// code produced by vite
const modules = {
  './dir/foo.js': () => import('./dir/foo.js'),
}
```

#### Named Imports

It's possible to only import parts of the modules with the `import` options.

```ts twoslash
import 'vite/client'
// ---cut---
const modules = import.meta.glob('./dir/*.js', { import: 'setup' })
```

```ts
// code produced by vite
const modules = {
  './dir/bar.js': () => import('./dir/bar.js').then((m) => m.setup),
  './dir/foo.js': () => import('./dir/foo.js').then((m) => m.setup),
}
```

When combined with `eager` it's even possible to have tree-shaking enabled for those modules.

```ts twoslash
import 'vite/client'
// ---cut---
const modules = import.meta.glob('./dir/*.js', {
  import: 'setup',
  eager: true,
})
```

```ts
// code produced by vite:
import { setup as __vite_glob_0_0 } from './dir/bar.js'
import { setup as __vite_glob_0_1 } from './dir/foo.js'
const modules = {
  './dir/bar.js': __vite_glob_0_0,
  './dir/foo.js': __vite_glob_0_1,
}
```

Set `import` to `default` to import the default export.

```ts twoslash
import 'vite/client'
// ---cut---
const modules = import.meta.glob('./dir/*.js', {
  import: 'default',
  eager: true,
})
```

```ts
// code produced by vite:
import { default as __vite_glob_0_0 } from './dir/bar.js'
import { default as __vite_glob_0_1 } from './dir/foo.js'
const modules = {
  './dir/bar.js': __vite_glob_0_0,
  './dir/foo.js': __vite_glob_0_1,
}
```

#### Custom Queries

You can also use the `query` option to provide queries to imports, for example, to import assets [as a string](/guide/assets.html#importing-asset-as-string) or [as a url](/guide/assets.html#importing-asset-as-url):

```ts twoslash
import 'vite/client'
// ---cut---
const moduleStrings = import.meta.glob('./dir/*.svg', {
  query: '?raw',
  import: 'default',
})
const moduleUrls = import.meta.glob('./dir/*.svg', {
  query: '?url',
  import: 'default',
})
```

```ts
// code produced by vite:
const moduleStrings = {
  './dir/bar.svg': () => import('./dir/bar.svg?raw').then((m) => m['default']),
  './dir/foo.svg': () => import('./dir/foo.svg?raw').then((m) => m['default']),
}
const moduleUrls = {
  './dir/bar.svg': () => import('./dir/bar.svg?url').then((m) => m['default']),
  './dir/foo.svg': () => import('./dir/foo.svg?url').then((m) => m['default']),
}
```

You can also provide custom queries for other plugins to consume:

```ts twoslash
import 'vite/client'
// ---cut---
const modules = import.meta.glob('./dir/*.js', {
  query: { foo: 'bar', bar: true },
})
```

#### Base Path

You can also use the `base` option to provide base path for the imports:

```ts twoslash
import 'vite/client'
// ---cut---
const modulesWithBase = import.meta.glob('./**/*.js', {
  base: './base',
})
```

```ts
// code produced by vite:
const modulesWithBase = {
  './dir/foo.js': () => import('./base/dir/foo.js'),
  './dir/bar.js': () => import('./base/dir/bar.js'),
}
```

The base option can only be a directory path relative to the importer file or absolute against the project root. Aliases and virtual modules aren't supported.

Only the globs that are relative paths are interpreted as relative to the resolved base.

All the resulting module keys are modified to be relative to the base if provided.

#### Case Sensitive Matching

By default, glob pattern matching is case-sensitive. You can use the `caseSensitive` option to change this behavior:

```ts twoslash
import 'vite/client'
// ---cut---
const modules = import.meta.glob('./dir/module*.js', {
  caseSensitive: false,
})
```

With `caseSensitive: false`, the glob will match files regardless of case (e.g., `Module.js`, `module.js`, `MODULE.js` will all be matched by `module*.js`).

### Glob Import Caveats

Note that:

- This is a Vite-only feature and is not a web or ES standard.
- The glob patterns are treated like import specifiers: they must be either relative (start with `./`) or absolute (start with `/`, resolved relative to project root) or an alias path (see [`resolve.alias` option](/config/shared-options.md#resolve-alias)).
- The glob matching is done via [`tinyglobby`](https://github.com/SuperchupuDev/tinyglobby) - check out its documentation for [supported glob patterns](https://superchupu.dev/tinyglobby/comparison).
- You should also be aware that all the arguments in the `import.meta.glob` must be **passed as literals**. You can NOT use variables or expressions in them.

## Dynamic Import

Similar to [glob import](#glob-import), Vite also supports dynamic import with variables.

```ts
const module = await import(`./dir/${file}.js`)
```

Note that variables only represent file names one level deep. If `file` is `'foo/bar'`, the import would fail. For more advanced usage, you can use the [glob import](#glob-import) feature.

Also note that the dynamic import must match the following rules to be bundled:

- Imports must start with `./` or `../`: ``import(`./dir/${foo}.js`)`` is valid, but ``import(`${foo}.js`)`` is not.
- Imports must end with a file extension: ``import(`./dir/${foo}.js`)`` is valid, but ``import(`./dir/${foo}`)`` is not.
- Imports to the own directory must specify a file name pattern: ``import(`./prefix-${foo}.js`)`` is valid, but ``import(`./${foo}.js`)`` is not.

These rules are enforced to prevent accidentally importing files that are not intended to be bundled. For example, without these rules, `import(foo)` would bundle everything in the file system.

## WebAssembly

Vite supports importing pre-compiled `.wasm` files in two ways: directly as an [ES module](#esm-integration) when you only need the module's exports, or with [`?init`](#manual-initialization) when you need explicit control over instantiation.

### ESM Integration

A `.wasm` file can be imported directly. Vite reads the module's imports and exports from the binary, instantiates it, and re-exposes its exports as named ES module exports:

```js
import { add } from './add.wasm'

console.log(add(1, 2)) // 3
```

If the WebAssembly module declares imports of its own, Vite resolves them from JavaScript modules. Each import's module name is treated as an import specifier (resolved relative to the `.wasm` file) and the requested members are wired into the instance automatically.

This follows the [WebAssembly/ES Module Integration proposal](https://github.com/WebAssembly/esm-integration). Because a WebAssembly module is instantiated asynchronously, a directly imported `.wasm` file behaves as an async module and requires top-level `await` support.

::: tip TypeScript support

Since the types of `.wasm` files are unknown, TypeScript will report errors like `Module '"*.wasm"' has no exported member 'add'`. To fix this, enable [`allowArbitraryExtensions`](https://www.typescriptlang.org/tsconfig/#allowArbitraryExtensions) in your `tsconfig.json` and create a declaration file next to your `.wasm` file. With `allowArbitraryExtensions` enabled, TypeScript will look for a declaration file named `{filename}.d.wasm.ts` when resolving a `.wasm` import. For example, for `add.wasm`, create `add.d.wasm.ts`:

```ts [add.d.wasm.ts]
export function add(a: number, b: number): number
```

:::

### Manual Initialization

When you need control over when and how the module is instantiated, import it with `?init`. The default export will be an initialization function that returns a Promise of the [`WebAssembly.Instance`](https://developer.mozilla.org/en-US/docs/WebAssembly/JavaScript_interface/Instance):

```js twoslash
import 'vite/client'
// ---cut---
import init from './example.wasm?init'

init().then((instance) => {
  instance.exports.test()
})
```

The init function can also take an importObject which is passed along to [`WebAssembly.instantiate`](https://developer.mozilla.org/en-US/docs/WebAssembly/JavaScript_interface/instantiate) as its second argument:

```js twoslash
import 'vite/client'
import init from './example.wasm?init'
// ---cut---
init({
  imports: {
    someFunc: () => {
      /* ... */
    },
  },
}).then(() => {
  /* ... */
})
```

In the production build, `.wasm` files smaller than `assetsInlineLimit` will be inlined as base64 strings. Otherwise, they will be treated as a [static asset](./assets) and fetched on-demand.

::: warning For SSR build, Node.js compatible runtimes are only supported

Due to the lack of a universal way to load a file, the internal implementation for both direct `.wasm` imports and `.wasm?init` relies on the `node:fs` module. This means that these features will only work in Node.js compatible runtimes for SSR builds.

:::

### Accessing the WebAssembly Module

If you need access to the `Module` object, e.g. to instantiate it multiple times, use an [explicit URL import](./assets#explicit-url-imports) to resolve the asset, and then perform the instantiation:

```js twoslash
import 'vite/client'
// ---cut---
import wasmUrl from 'foo.wasm?url'

const main = async () => {
  const responsePromise = fetch(wasmUrl)
  const { module, instance } =
    await WebAssembly.instantiateStreaming(responsePromise)
  /* ... */
}

main()
```

## Web Workers

### Import with Constructors

A web worker script can be imported using [`new Worker()`](https://developer.mozilla.org/en-US/docs/Web/API/Worker/Worker) and [`new SharedWorker()`](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker/SharedWorker). Compared to the worker suffixes, this syntax leans closer to the standards and is the **recommended** way to create workers.

```ts
const worker = new Worker(new URL('./worker.js', import.meta.url))
```

The worker constructor also accepts options, which can be used to create "module" workers:

```ts
const worker = new Worker(new URL('./worker.js', import.meta.url), {
  type: 'module',
})
```

The worker detection will only work if the `new URL()` constructor is used directly inside the `new Worker()` declaration. Otherwise it is handled as a [static asset URL](./assets#new-url-url-import-meta-url) instead. Additionally, all options parameters must be static values (i.e. string literals).

### Import with Query Suffixes

A web worker script can be directly imported by appending `?worker` or `?sharedworker` to the import request. The default export will be a custom worker constructor:

```js twoslash
import 'vite/client'
// ---cut---
import MyWorker from './worker?worker'

const worker = new MyWorker()
```

The worker script can also use ESM `import` statements instead of `importScripts()`. **Note**: During development this relies on [browser native support](https://caniuse.com/?search=module%20worker), but for the production build it is compiled away.

By default, the worker script will be emitted as a separate chunk in the production build. If you wish to inline the worker as base64 strings, add the `inline` query:

```js twoslash
import 'vite/client'
// ---cut---
import MyWorker from './worker?worker&inline'
```

If you wish to retrieve the worker as a URL, add the `url` query:

```js twoslash
import 'vite/client'
// ---cut---
import MyWorker from './worker?worker&url'
```

See [Worker Options](/config/worker-options.md) for details on configuring the bundling of all workers.

## Content Security Policy (CSP)

To deploy CSP, certain directives or configs must be set due to Vite's internals.

### [`'nonce-{RANDOM}'`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/Sources#nonce-base64-value)

When [`html.cspNonce`](/config/shared-options#html-cspnonce) is set, Vite adds a nonce attribute with the specified value to any `<script>` and `<style>` tags, as well as `<link>` tags for stylesheets and module preloading. Additionally, when this option is set, Vite will inject a meta tag (`<meta property="csp-nonce" nonce="PLACEHOLDER" />`).

The nonce value of a meta tag with `property="csp-nonce"` will be used by Vite whenever necessary during both dev and after build.

:::warning
Ensure that you replace the placeholder with a unique value for each request. This is important to prevent bypassing a resource's policy, which can otherwise be easily done.
:::

### [`data:`](<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/Sources#scheme-source:~:text=schemes%20(not%20recommended).-,data%3A,-Allows%20data%3A>)

By default, during build, Vite inlines small assets as data URIs. Allowing `data:` for related directives (e.g. [`img-src`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/img-src), [`font-src`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/font-src)), or, disabling it by setting [`build.assetsInlineLimit: 0`](/config/build-options#build-assetsinlinelimit) is necessary.

:::warning
Do not allow `data:` for [`script-src`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src). It will allow injection of arbitrary scripts.
:::

## License

Vite can generate a file of all the dependencies' licenses used in the build with the [`build.license`](/config/build-options.md#build-license) option. It can be hosted to display and acknowledge the dependencies used by the app.

```js twoslash [vite.config.js]
import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    license: true,
  },
})
```

This will generate a `.vite/license.md` file with an output that may look like this:

```md
# Licenses

The app bundles dependencies which contain the following licenses:

## dep-1 - 1.2.3 (CC0-1.0)

CC0 1.0 Universal

...

## dep-2 - 4.5.6 (MIT)

MIT License

...
```

To serve the file at a different path, you can pass `{ fileName: 'license.md' }` for example, so that it's served at `https://example.com/license.md`. See the [`build.license`](/config/build-options.md#build-license) docs for more information.

## Build Optimizations

> Features listed below are automatically applied (except for the experimental chunk import map feature) as part of the build process and there is no need for explicit configuration unless you want to disable them.

### CSS Code Splitting

Vite automatically extracts the CSS used by modules in an async chunk and generates a separate file for it. The CSS file is automatically loaded via a `<link>` tag when the associated async chunk is loaded, and the async chunk is guaranteed to only be evaluated after the CSS is loaded to avoid [FOUC](https://en.wikipedia.org/wiki/Flash_of_unstyled_content#:~:text=A%20flash%20of%20unstyled%20content,before%20all%20information%20is%20retrieved.).

If you'd rather have all the CSS extracted into a single file, you can disable CSS code splitting by setting [`build.cssCodeSplit`](/config/build-options.md#build-csscodesplit) to `false`.

### Preload Directives Generation

Vite automatically generates `<link rel="modulepreload">` directives for entry chunks and their direct imports in the built HTML.

### Async Chunk Loading Optimization

In real world applications, Rollup often generates "common" chunks - code that is shared between two or more other chunks. Combined with dynamic imports, it is quite common to have the following scenario:

<script setup>
import graphSvg from '../images/graph.svg?raw'
</script>
<svg-image :svg="graphSvg" />

In the non-optimized scenarios, when async chunk `A` is imported, the browser will have to request and parse `A` before it can figure out that it also needs the common chunk `C`. This results in an extra network roundtrip:

```
Entry ---> A ---> C
```

Vite automatically rewrites code-split dynamic import calls with a preload step so that when `A` is requested, `C` is fetched **in parallel**:

```
Entry ---> (A + C)
```

It is possible for `C` to have further imports, which will result in even more roundtrips in the un-optimized scenario. Vite's optimization will trace all the direct imports to completely eliminate the roundtrips regardless of import depth.

### Chunk Import Map Optimization

To improve the cache hit rate of chunks, Vite can create an import map for chunks. This prevents the cascading cache invalidation issue, which is a problem with ES Modules.

For example, consider the following scenario:

```
Entry --> A ---> C
```

If `C` is updated, the only chunk that inherently needs to be invalidated is `C`. However, if `A` references `C` via a normal URL in a static import (i.e. the hash of `C` is included in the URL), the content of `A` is changed, thus `A` would also need to be invalidated. The same applies to `Entry`.

By utilizing the import maps feature, this issue can be avoided. When this optimization is enabled, Vite will create an import map that maps each chunk's ID to its URL and uses the chunk ID in the import statements instead of the URL. This way, when a chunk is updated, only the updated chunk needs to be invalidated, while the chunks that reference it will not be invalidated.

Note that this optimization currently does not apply to CSS and assets. If you update an asset, the chunks that reference it will be invalidated. That said, the invalidation would not cascade and the chunk importing the invalidated chunk would not be invalidated.

To enable this feature, set [`build.chunkImportMap`](/config/build-options.md#build-chunkimportmap) to `true`.