Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(deps): update jest monorepo to v29 (major) #195

Open
wants to merge 7 commits into
base: next
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -16,8 +16,8 @@ module.exports = {
'plugin:vue-libs/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/eslint-recommended',
'prettier/@typescript-eslint',
'plugin:prettier/recommended'
'plugin:prettier/recommended',
'prettier'
],
plugins: ['@typescript-eslint'],
parser: 'vue-eslint-parser',
@@ -29,6 +29,8 @@ module.exports = {
'object-curly-spacing': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/member-delimiter-style': 'off',
'@typescript-eslint/no-use-before-define': 'off'
'@typescript-eslint/no-use-before-define': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/ban-ts-comment': 'off'
}
}
2 changes: 1 addition & 1 deletion .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# These are supported funding model platforms

github: kazupon
patreon: kazupon
patreon: # kazupon
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
Empty file removed .github/ISSUE_TEMPLATE.md
Empty file.
68 changes: 68 additions & 0 deletions .github/ISSUE_TEMPLATE/bug-report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: "\U0001F41E Bug report"
description: Report an issue
labels: ['Status: Review Needed']
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
- type: textarea
id: bug-description
attributes:
label: Reporting a bug?
description: A clear and concise description of what the bug is. If you intend to submit a PR for this issue, tell us in the description. Thanks!
placeholder: Bug description
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: Expected behavior
description: A clear and concise description of what you expected to happen.
placeholder: Expected behavior
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: Reproduction
description: |
Please provide a link to a repo that can reproduce the problem you ran into. A reproduction is required unless you are absolutely sure that the issue is obvious and the provided information is enough to understand the problem. If a report is vague (e.g. just a generic error message) and has no reproduction, it will receive a "Status: Need More Info" label. If no reproduction is provided after 5 days, it will be closed.
placeholder: Reproduction
validations:
required: true
- type: textarea
id: system-info
attributes:
label: System Info
description: Output of `npx envinfo --system --npmPackages webpack,vue,vue-i18n,@intlify/vue-i18n-loader --binaries --browsers`
render: shell
placeholder: System, Binaries, Browsers
validations:
required: true
- type: textarea
id: screenshot
attributes:
label: Screenshot
description: If applicable, add screenshots to help explain your problem
placeholder: screnshot
- type: textarea
id: additional-context
attributes:
label: Additional context
description: Add any other context about the problem here
placeholder: more context here
- type: checkboxes
id: checkboxes
attributes:
label: Validations
description: Before submitting the issue, please make sure you do the following
options:
- label: Read the [Contributing Guidelines](https://github.com/intlify/vue-i18n-loader/blob/v1.x/.github/CONTRIBUTING.md)
required: true
- label: Read the README
required: true
- label: Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
required: true
- label: Check that this is a concrete bug. For Q&A open a [GitHub Discussion](https://github.com/intlify/bundle-tools/discussions).
required: true
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Questions & Discussions
url: https://github.com/intlify/bundle-tools/discussions
about: Use GitHub discussions for message-board style questions and discussions.
44 changes: 44 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: "\U0001F680 New feature proposal"
description: Propose a new feature
labels: ["Status: Proposal"]
body:
- type: markdown
attributes:
value: |
Thanks for your interest in the project and taking the time to fill out this feature report!
- type: textarea
id: feature-description
attributes:
label: Clear and concise description of the problem
description: If you intend to submit a PR for this issue, tell us in the description. Thanks!
validations:
required: true
- type: textarea
id: suggested-solution
attributes:
label: Suggested solution
description: "In module [xy] we could provide following implementation..."
validations:
required: true
- type: textarea
id: alternative
attributes:
label: Alternative
description: Clear and concise description of any alternative solutions or features you've considered.
- type: textarea
id: additional-context
attributes:
label: Additional context
description: Any other context or screenshots about the feature request here.
- type: checkboxes
id: checkboxes
attributes:
label: Validations
description: Before submitting the issue, please make sure you do the following
options:
- label: Read the [Contributing Guidelines](https://github.com/intlify/vue-i18n-loader/blob/v1.x/.github/CONTRIBUTING.md)
required: true
- label: Read the README
required: true
- label: Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
required: true
Empty file removed .github/PULL_REQUEST_TEMPLATE.md
Empty file.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@

## v1.1.0 (2021-03-03)

#### :star: Features
* [#173](https://github.com/intlify/vue-i18n-loader/pull/173) feat: intlify vue plugin for v1 ([@kazupon](https://github.com/kazupon))

#### Committers: 1
- kazuya kawaguchi ([@kazupon](https://github.com/kazupon))


## v1.0.0 (2020-04-07)

#### :pencil: Documentation
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -5,13 +5,19 @@
<p align="center">
<a href="https://github.com/intlify/vue-i18n-loader/actions?query=workflow%3ATest"><img src="https://github.com/intlify/vue-i18n-loader/workflows/Test/badge.svg" alt="Build Status"></a>
<a href="https://www.npmjs.com/package/@intlify/vue-i18n-loader"><img src="https://img.shields.io/npm/v/@intlify/vue-i18n-loader.svg" alt="npm"></a>
<a href="https://devtoken.rocks/package/@intlify/vue-i18n-loader"><img src="https://badge.devtoken.rocks/@intlify/vue-i18n-loader" alt="@intlify/vue-i18n-loader Dev Token"/></a>
</p>

<p align="center">vue-i18n loader for custom blocks</p>
<p align="center">webpack loader for Vue I18n</p>

<br/>

## :warning: Notice

This package is maintained for Vue I18n v8 (Vue 2).

If you want to use Vue I18n v9 (Vue 3) or later, See the [`@intlify/bundle-tools`](https://github.com/intlify/bundle-tools) repo.


## :cd: Installation

$ npm i --save-dev @intlify/vue-i18n-loader
53 changes: 27 additions & 26 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@intlify/vue-i18n-loader",
"description": "vue-i18n loader for custom blocks",
"version": "1.0.0",
"description": "webpack loader for Vue I18n",
"version": "1.1.0",
"author": {
"name": "kazuya kawaguchi",
"email": "[email protected]"
@@ -24,46 +24,46 @@
}
},
"dependencies": {
"@intlify/shared": "^9.0.0",
"js-yaml": "^3.13.1",
"json5": "^2.1.1"
},
"devDependencies": {
"@types/jest": "^25.0.0",
"@types/jest": "^29.0.0",
"@types/js-yaml": "^3.12.1",
"@types/jsdom": "^16.0.0",
"@types/jsdom": "^16.2.5",
"@types/json5": "^0.0.30",
"@types/memory-fs": "^0.3.2",
"@types/node": "^13.1.4",
"@types/webpack": "^4.41.1",
"@types/node": "^14.14.10",
"@types/webpack": "^4.41.26",
"@types/webpack-merge": "^4.1.5",
"@typescript-eslint/eslint-plugin": "^2.26.0",
"@typescript-eslint/parser": "^2.26.0",
"@typescript-eslint/typescript-estree": "^2.26.0",
"@typescript-eslint/eslint-plugin": "^4.15.0",
"@typescript-eslint/parser": "^4.15.0",
"babel-loader": "^8.1.0",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.10.1",
"eslint-plugin-prettier": "^3.1.2",
"eslint": "^7.21.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue-libs": "^4.0.0",
"jest": "^25.2.4",
"jest": "^29.0.0",
"jest-puppeteer": "^4.4.0",
"jest-watch-typeahead": "^0.5.0",
"jsdom": "^16.0.0",
"lerna-changelog": "^1.0.0",
"jest-watch-typeahead": "^0.6.0",
"jsdom": "^16.4.0",
"lerna-changelog": "^1.0.1",
"memory-fs": "^0.5.0",
"opener": "^1.5.1",
"opener": "^1.5.2",
"prettier": "^2.0.4",
"puppeteer": "^2.1.1",
"shipjs": "^0.18.0",
"ts-jest": "^25.3.0",
"typescript": "^3.8.3",
"typescript-eslint-language-service": "^2.0.3",
"shipjs": "^0.26.0",
"ts-jest": "^29.0.0",
"typescript": "^4.1.3",
"typescript-eslint-language-service": "^4.1.3",
"vue": "^2.6.11",
"vue-i18n": "^8.16.0",
"vue-loader": "^15.7.0",
"vue-i18n": "^8.23.0",
"vue-loader": "^15.9.6",
"vue-template-compiler": "^2.6.11",
"webpack": "^4.42.1",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3",
"webpack": "^4.46.0",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0",
"webpack-merge": "^4.2.2"
},
"engines": {
@@ -95,6 +95,7 @@
"lint:fix": "yarn lint --fix",
"release:prepare": "shipjs prepare",
"release:trigger": "shipjs trigger",
"fix": "yarn format:fix && yarn lint:fix",
"format": "prettier --config .prettierrc --ignore-path .prettierignore '**/*.{js,json,html}'",
"format:fix": "yarn format --write",
"test": "yarn lint && yarn test:cover && yarn test:e2e",
2 changes: 1 addition & 1 deletion ship.config.js
Original file line number Diff line number Diff line change
@@ -36,7 +36,7 @@ async function commitChangelog(current, next) {
}

module.exports = {
mergeStrategy: { toSameBranch: ['master'] },
mergeStrategy: { toSameBranch: ['v1.x'] },
monorepo: undefined,
updateChangelog: false,
beforeCommitChanges: ({ nextVersion, exec, dir }) => {
34 changes: 34 additions & 0 deletions src/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
;(async () => {
try {
await import('vue-i18n')
} catch (e) {
throw new Error(
'@intlify/vue-i18n-loader requires vue-i18n to be present in the dependency tree.'
)
}
})()

import webpack from 'webpack'

declare class IntlifyVuePlugin {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
constructor(optoins: Record<string, any>)
apply(compiler: webpack.Compiler): void
}

let Plugin: typeof IntlifyVuePlugin

console.warn(
`[@intlify/vue-i18n-loader] IntlifyVuePlugin is experimental! This plugin is used for Intlify tools. Don't use this plugin to enhancement Component options of your application.`
)
// console.log('[@intlify/vue-i18n-loader] webpack version:', webpack.version)

if (webpack.version && webpack.version[0] > '4') {
// webpack5 and upper
Plugin = require('./pluginWebpack5').default // eslint-disable-line @typescript-eslint/no-var-requires
} else {
// webpack4 and lower
Plugin = require('./pluginWebpack4').default // eslint-disable-line @typescript-eslint/no-var-requires
}

export default Plugin
238 changes: 238 additions & 0 deletions src/pluginWebpack4.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

import { parse as parseQuery } from 'querystring'
import webpack from 'webpack'
import { ReplaceSource } from 'webpack-sources'
import { isFunction, isObject, isRegExp, isString } from '@intlify/shared'
const Dependency = require('webpack/lib/Dependency') // eslint-disable-line @typescript-eslint/no-var-requires
const NullFactory = require('webpack/lib/NullFactory') // eslint-disable-line @typescript-eslint/no-var-requires

const PLUGIN_ID = 'IntlifyVuePlugin'

interface NormalModule extends webpack.compilation.Module {
resource?: string
request?: string
userRequest?: string
addDependency(dep: unknown): void
parser?: webpack.compilation.normalModuleFactory.Parser
loaders?: Array<{
loader: string
options: any
indent?: string
type?: string
}>
}

type InjectionValues = Record<string, any>

class VueComponentDependency extends Dependency {
static Template: VueComponentDependencyTemplate
script?: NormalModule
template?: NormalModule
values: InjectionValues
statement: any

constructor(
script: NormalModule | undefined,
template: NormalModule | undefined,
values: InjectionValues,
statement: any
) {
super()
this.script = script
this.template = template
this.values = values
this.statement = statement
}

get type() {
return 'harmony export expression'
}

getExports() {
return {
exports: ['default'],
dependencies: undefined
}
}

updateHash(hash: any) {
super.updateHash(hash)
const scriptModule = this.script
hash.update(
(scriptModule &&
(!scriptModule.buildMeta || scriptModule.buildMeta.exportsType)) + ''
)
hash.update((scriptModule && scriptModule.id) + '')
const templateModule = this.template
hash.update(
(templateModule &&
(!templateModule.buildMeta || templateModule.buildMeta.exportsType)) +
''
)
hash.update((templateModule && templateModule.id) + '')
}
}

function stringifyObj(obj: Record<string, any>): string {
return `Object({${Object.keys(obj)
.map(key => {
const code = obj[key]
return `${JSON.stringify(key)}:${toCode(code)}`
})
.join(',')}})`
}

function toCode(code: any): string {
if (code === null) {
return 'null'
}

if (code === undefined) {
return 'undefined'
}

if (isString(code)) {
return JSON.stringify(code)
}

if (isRegExp(code) && code.toString) {
return code.toString()
}

if (isFunction(code) && code.toString) {
return '(' + code.toString() + ')'
}

if (isObject(code)) {
return stringifyObj(code)
}

return code + ''
}

function generateCode(dep: VueComponentDependency, importVar: string): string {
const injectionCodes = ['']
Object.keys(dep.values).forEach(key => {
const code = dep.values[key]
if (isFunction(code)) {
injectionCodes.push(`${importVar}.${key} = ${JSON.stringify(code(dep))}`)
} else {
injectionCodes.push(`${importVar}.${key} = ${toCode(code)}`)
}
})

let ret = injectionCodes.join('\n')
ret = ret.length > 0 ? `\n${ret}\n` : ''
return (ret += `/* harmony default export */ __webpack_exports__["default"] = (${importVar});`)
}

class VueComponentDependencyTemplate {
apply(dep: VueComponentDependency, source: ReplaceSource) {
const repleacements = source.replacements
const orgReplace = repleacements[repleacements.length - 1]
const code = generateCode(dep, 'component.exports')
// console.log('generateCode', code, dep.statement, orgReplace)
source.replace(orgReplace.start, orgReplace.end, code)
}
}

VueComponentDependency.Template = VueComponentDependencyTemplate

function getScriptBlockModule(parser: any): NormalModule | undefined {
return parser.state.current.dependencies.find((dep: any) => {
const req = dep.userRequest || dep.request
if (req && dep.originModule) {
const query = parseQuery(req)
return query.type === 'script' && query.lang === 'js'
} else {
return false
}
})
}

function getTemplateBlockModule(parser: any): NormalModule | undefined {
return parser.state.current.dependencies.find((dep: any) => {
const req = dep.userRequest || dep.request
if (req && dep.originModule) {
const query = parseQuery(req)
return query.type === 'template'
} else {
return false
}
})
}

function toVueComponentDependency(parser: any, values: InjectionValues) {
return function vueComponentDependencyw(statement: any) {
// console.log('toVueComponentDependency##statement', statement)
const dep = new VueComponentDependency(
getScriptBlockModule(parser),
getTemplateBlockModule(parser),
values,
statement
)
// dep.loc = statement.loc
parser.state.current.addDependency(dep)
return true
}
}

export default class IntlifyVuePlugin implements webpack.Plugin {
injections: InjectionValues

constructor(injections: InjectionValues = {}) {
this.injections = injections
}

apply(compiler: webpack.Compiler): void {
const injections = this.injections

compiler.hooks.compilation.tap(
PLUGIN_ID,
(compilation, { normalModuleFactory }) => {
compilation.dependencyFactories.set(
// @ts-ignore
VueComponentDependency,
new NullFactory()
)
compilation.dependencyTemplates.set(
// @ts-ignore
VueComponentDependency,
// @ts-ignore
new VueComponentDependency.Template()
)

const handler = (
parser: webpack.compilation.normalModuleFactory.Parser
) => {
parser.hooks.exportExpression.tap(
PLUGIN_ID,
(statement, declaration) => {
if (
(parser as any).state.module.resource.endsWith('.vue') &&
declaration.object.name === 'component' &&
declaration.property.name === 'exports'
) {
// console.log('exportExpression', statement, declaration)
return toVueComponentDependency(parser, injections)(statement)
}
}
)
}

normalModuleFactory.hooks.parser
.for('javascript/auto')
.tap(PLUGIN_ID, handler)
normalModuleFactory.hooks.parser
.for('javascript/dynamic')
.tap(PLUGIN_ID, handler)
normalModuleFactory.hooks.parser
.for('javascript/esm')
.tap(PLUGIN_ID, handler)
}
)
}
}

/* eslint-enable @typescript-eslint/no-explicit-any */
236 changes: 236 additions & 0 deletions src/pluginWebpack5.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

import { parse as parseQuery } from 'querystring'
import webpack from 'webpack'
import { isFunction, isObject, isRegExp, isString } from '@intlify/shared'
const Dependency = require('webpack/lib/Dependency') // eslint-disable-line @typescript-eslint/no-var-requires
const NullFactory = require('webpack/lib/NullFactory') // eslint-disable-line @typescript-eslint/no-var-requires

const PLUGIN_ID = 'IntlifyVuePlugin'

type InjectionValues = Record<string, any>

class VueComponentDependency extends Dependency {
static Template: VueComponentDependencyTemplate
script?: any /* webpack.Dependency */
template?: any /* webpack.Dependency */
values: InjectionValues
statement: any

constructor(
script: any /* webpack.Dependency | undefined, */,
template: any /* webpack.Dependency | undefined, */,
values: InjectionValues,
statement: any
) {
super()
this.script = script
this.template = template
this.values = values
this.statement = statement
}

// @ts-ignore
get type(): string {
return 'harmony export expression'
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
getExports(moduleGraph: any /* webpack.ModuleGraph */) {
return {
exports: ['default'],
dependencies: undefined
}
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
updateHash(hash: any, context: any): void {
super.updateHash(hash, context)
const scriptModule: any = this.script
hash.update(
(scriptModule &&
(!scriptModule.buildMeta || scriptModule.buildMeta.exportsType)) + ''
)
hash.update((scriptModule && scriptModule.id) + '')
const templateModule: any = this.template
hash.update(
(templateModule &&
(!templateModule.buildMeta || templateModule.buildMeta.exportsType)) +
''
)
hash.update((templateModule && templateModule.id) + '')
}
}

function stringifyObj(obj: Record<string, any>): string {
return `Object({${Object.keys(obj)
.map(key => {
const code = obj[key]
return `${JSON.stringify(key)}:${toCode(code)}`
})
.join(',')}})`
}

function toCode(code: any): string {
if (code === null) {
return 'null'
}

if (code === undefined) {
return 'undefined'
}

if (isString(code)) {
return JSON.stringify(code)
}

if (isRegExp(code) && code.toString) {
return code.toString()
}

if (isFunction(code) && code.toString) {
return '(' + code.toString() + ')'
}

if (isObject(code)) {
return stringifyObj(code)
}

return code + ''
}

function generateCode(dep: VueComponentDependency, importVar: string): string {
const injectionCodes = ['']
Object.keys(dep.values).forEach(key => {
const code = dep.values[key]
if (isFunction(code)) {
injectionCodes.push(`${importVar}.${key} = ${JSON.stringify(code(dep))}`)
} else {
injectionCodes.push(`${importVar}.${key} = ${toCode(code)}`)
}
})

let ret = injectionCodes.join('\n')
ret = ret.length > 0 ? `\n${ret}\n` : ''
return (ret += `/* harmony default export */ __webpack_exports__["default"] = (${importVar});`)
}

class VueComponentDependencyTemplate {
apply(
dep: VueComponentDependency,
source: any /* webpack.sources.ReplaceSource */
) {
const repleacements = source.replacements
const orgReplace = repleacements[repleacements.length - 1]
const code = generateCode(dep, 'component.exports')
// console.log('generateCode', code, dep.statement, orgReplace)
source.replace(orgReplace.start, orgReplace.end, code)
}
}

VueComponentDependency.Template = VueComponentDependencyTemplate

function getScriptBlockModule(
parser: any /* webpack.javascript.JavascriptParser */
) /* : webpack.Dependency | undefined */ {
return parser.state.current.dependencies.find((dep: any) => {
const req = dep.userRequest || dep.request
if (req && dep.originModule) {
const query = parseQuery(req)
return query.type === 'script' && query.lang === 'js'
} else {
return false
}
})
}

function getTemplateBlockModule(
parser: any /* webpack.javascript.JavascriptParser */
) /* : webpack.Dependency | undefined */ {
return parser.state.current.dependencies.find((dep: any) => {
const req = dep.userRequest || dep.request
if (req && dep.originModule) {
const query = parseQuery(req)
return query.type === 'template'
} else {
return false
}
})
}

function toVueComponentDependency(
parser: any /* webpack.javascript.JavascriptParser */,
values: InjectionValues
) {
return function vueComponentDependencyw(statement: any) {
// console.log('toVueComponentDependency##statement', statement)
const dep = new VueComponentDependency(
getScriptBlockModule(parser),
getTemplateBlockModule(parser),
values,
statement
)
// dep.loc = statement.loc
parser.state.current.addDependency(dep)
return true
}
}

export default class IntlifyVuePlugin {
injections: InjectionValues

constructor(injections: InjectionValues = {}) {
this.injections = injections
}

apply(compiler: webpack.Compiler): void {
const injections = this.injections

compiler.hooks.compilation.tap(
PLUGIN_ID,
(compilation, { normalModuleFactory }) => {
compilation.dependencyFactories.set(
// @ts-ignore
VueComponentDependency,
new NullFactory()
)
compilation.dependencyTemplates.set(
// @ts-ignore
VueComponentDependency,
// @ts-ignore
new VueComponentDependency.Template()
)

const handler = (
parser: any /* webpack.javascript.JavascriptParser */
) => {
parser.hooks.exportExpression.tap(
PLUGIN_ID,
(statement: any, declaration: any) => {
if (
parser.state.module.resource.endsWith('.vue') &&
declaration.object.name === 'component' &&
declaration.property.name === 'exports'
) {
// console.log('exportExpression', statement, declaration)
return toVueComponentDependency(parser, injections)(statement)
}
}
)
}

normalModuleFactory.hooks.parser
.for('javascript/auto')
.tap(PLUGIN_ID, handler)
normalModuleFactory.hooks.parser
.for('javascript/dynamic')
.tap(PLUGIN_ID, handler)
normalModuleFactory.hooks.parser
.for('javascript/esm')
.tap(PLUGIN_ID, handler)
}
)
}
}

/* eslint-enable @typescript-eslint/no-explicit-any */
15 changes: 15 additions & 0 deletions test/fixtures/plugin/basic.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<template>
<h1>Meta</h1>
</template>

<script>
export default {
name: 'Meta'
}
</script>

<i18n>
{
"ja": "hello"
}
</i18n>
5 changes: 5 additions & 0 deletions test/fixtures/plugin/script.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<script>
export default {
name: 'Meta'
}
</script>
35 changes: 35 additions & 0 deletions test/plugin.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { bundleAndRun, bundleEx } from './utils'

const options = {
a: 1,
b: 'hello',
c: {
a: 1,
nest: {
foo: 'hello'
}
},
d: () => 'hello'
}

test('basic', async () => {
const { module } = await bundleAndRun('./plugin/basic.vue', bundleEx, {
intlify: options
})
expect(module.a).toEqual(1)
expect(module.b).toEqual('hello')
expect(module.c.a).toEqual(1)
expect(module.c.nest.foo).toEqual('hello')
expect(module.d).toEqual('hello')
})

test('script only', async () => {
const { module } = await bundleAndRun('./plugin/script.vue', bundleEx, {
intlify: options
})
expect(module.a).toEqual(1)
expect(module.b).toEqual('hello')
expect(module.c.a).toEqual(1)
expect(module.c.nest.foo).toEqual('hello')
expect(module.d).toEqual('hello')
})
80 changes: 74 additions & 6 deletions test/utils.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

import path from 'path'
import webpack from 'webpack'
import merge from 'webpack-merge'
import memoryfs from 'memory-fs'
import { JSDOM, VirtualConsole, DOMWindow } from 'jsdom'
import { VueLoaderPlugin } from 'vue-loader'
import IntlifyVuePlugin from '../src/plugin'

type BundleResolve = {
code: string
stats: webpack.Stats
}

type BundleResolveResolve = BundleResolve & {
jsdomError: any // eslint-disable-line @typescript-eslint/no-explicit-any
instance: any // eslint-disable-line @typescript-eslint/no-explicit-any
jsdomError: any
instance: any
window: DOMWindow
module: any // eslint-disable-line @typescript-eslint/no-explicit-any
exports: any // eslint-disable-line @typescript-eslint/no-explicit-any
module: any
exports: any
}

export function bundle(fixture: string, options = {}): Promise<BundleResolve> {
export function bundle(
fixture: string,
options: Record<string, any> = {}
): Promise<BundleResolve> {
const baseConfig: webpack.Configuration = {
mode: 'development',
devtool: false,
@@ -67,11 +73,70 @@ export function bundle(fixture: string, options = {}): Promise<BundleResolve> {
})
}

export function bundleEx(
fixture: string,
options: Record<string, any> = {}
): Promise<BundleResolve> {
const baseConfig: webpack.Configuration = {
mode: 'development',
devtool: 'source-map',
entry: path.resolve(__dirname, './fixtures/entry.js'),
resolve: {
alias: {
'~target': path.resolve(__dirname, './fixtures', fixture)
}
},
output: {
path: '/',
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
resourceQuery: /blockType=i18n/,
type: 'javascript/auto',
use: [
{
loader: path.resolve(__dirname, '../src/index.ts'),
options
}
]
}
]
},
plugins: [new VueLoaderPlugin(), new IntlifyVuePlugin(options.intlify)]
}

const config = merge({}, baseConfig)
const compiler = webpack(config)

const mfs = new memoryfs() // eslint-disable-line
compiler.outputFileSystem = mfs

return new Promise((resolve, reject) => {
compiler.run((err, stats) => {
if (err) {
return reject(err)
}
if (stats.hasErrors()) {
return reject(new Error(stats.toJson().errors.join(' | ')))
}
resolve({ code: mfs.readFileSync('/bundle.js').toString(), stats })
})
})
}

export async function bundleAndRun(
fixture: string,
bundleFn = bundle,
config = {}
): Promise<BundleResolveResolve> {
const { code, stats } = await bundle(fixture, config)
const { code, stats } = await bundleFn(fixture, config)
// console.log('code', code)

let dom: JSDOM | null = null
let jsdomError
@@ -94,6 +159,7 @@ export async function bundleAndRun(
const { module, exports } = window
const instance = {}
if (module && module.beforeCreate) {
// eslint-disable-next-line @typescript-eslint/ban-types
module.beforeCreate.forEach((hook: Function) => hook.call(instance))
}

@@ -107,3 +173,5 @@ export async function bundleAndRun(
stats
})
}

/* eslint-enable @typescript-eslint/no-explicit-any */
4 changes: 2 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
"compilerOptions": {
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"target": "esnext", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
@@ -24,7 +24,7 @@

/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
"noImplicitAny": false, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
5,960 changes: 3,034 additions & 2,926 deletions yarn.lock

Large diffs are not rendered by default.