Red de conocimiento informático - Conocimiento informático - Cómo obtener la ruta del código fuente de un único archivo vue

Cómo obtener la ruta del código fuente de un único archivo vue

Esta pregunta comienza con una idea.

D2Admin es un programa de integración de front-end y back-end de código abierto. Inicialmente se basa en vue-cli2 y puede pasar a vue-cli3.

El autor, Lao Li. , quiere agregar un clic de alternancia en la esquina inferior derecha de la página para saltar a la página de github correspondiente al código fuente de la página actual.

Esta es realmente una característica muy útil. D2Admin tiene demasiadas páginas de demostración y resulta muy desagradable para los principiantes que no están familiarizados con la estructura del directorio del proyecto intentar ver el código fuente de una determinada página.

Estas páginas están unificadas en componentes .vue, por lo que hay una conversión: ¿Cómo obtener la ruta del código fuente del archivo único de vue?

Hay tres soluciones hasta el momento, el objetivo final es asignar su propia ruta a this.$options.__source. La última actualmente es la opción 3.

Opción 1: nodo + __filename

Usa directamente la variable __filename en el nodo:

Porque el paquete web compilará el archivo fuente convertido al módulo de nodo interno, por lo que el contenido del script en el archivo .vue también se convertirá.

El __filename se ejecutará durante la compilación y obtendrá directamente la ruta del archivo actual.

Para usar esta variable, también necesita habilitar node.__filename en la configuración del paquete web:

/* vue.config.js */

módulo. exports = {

// ...

chainWebpack: config => {

// ...

config.node

.set('__dirname', true) // lo mismo

.set('__filename', true)

}

};

Inconvenientes

Debes asignar valores manualmente en cada componente y no puedes usar mixin

En algunos archivos .vue, obténgalo a través de __filename. El camino no es exacto. En algunos archivos .vue, la ruta obtenida a través de __filename no es precisa y la ruta puede tener una cadena de consulta.

Al principio, el viejo y fuerte Li usó este método y configuró manualmente cientos de rutas. a cada componente, pero esto es mejor que escribir cada ruta manualmente

Opción 2: vue-loader + exponenFilename

En el nivel del cargador, vue-loader en realidad se proporciona una opción ExponFilename Cuando esta opción está habilitada,

cada componente .vue obtendrá esta opción.$options. La ruta exacta del componente vue this.$options.__file.

Esto solo requiere cambiar la configuración del cargador:

/* vue.config.js */

module.exports = {

// ...

chainWebpack: config => {

// ...

config.module

.rule( 'vue')

.use('vue-loader')

.loader('vue-loader')

.tap(opciones => {

opciones.exposeFilename = true

opciones de retorno

})

}

}

};

El entorno de desarrollo abre exponenFilename de forma predeterminada.

En este punto, el componente debería usar este archivo.$options.__, que es aproximadamente src/foo/bar.vue.

Desventajas

Por razones de seguridad, en un entorno de producción, vue-loader especifica __file como nombre de archivo en lugar de nombre de ruta, consulte la documentación para obtener más información.

Más tarde, cuando me enteré de este método, modifiqué el código inmediatamente y eliminé todo el código adicional en la opción 1. Resultó que los resultados eran inconsistentes en el entorno de producción, así que le di la vuelta.

Opción 3: Cargador + Bloque personalizado

Dado que la opción 2 no le permite usarlo en un entorno de producción, debe escribir su propio cargador para agregar la ruta al código fuente. código, donde puedes usar bloques personalizados.

Este método consiste en depurar lentamente el cargador personalizado, agregar el cargador personalizado A antes de vue-loader,

inyectar el código de bloque personalizado y luego en el alcance global. Esto se logra agregando cargador B para el bloque personalizado.

/* vue.config.js */

const VueFilenameInjector = require('./path/to/vue-filename-injector')

módulo .exports = {

chainWebpack: config => {

VueFilenameInjector(config, {

propName: '__source' // predeterminado

})

}

}

Referencia fuente: @d2-projects/d2-advance/tools/vue-filename-injector

.

└── vue-filename-injector

├── README.md

├─ index.js

└── src

├─ index.js

└── lib

├─ config.js

├─ inyector. js

└─ loader.js

vue-filename-injector/index.js:

const { blockName }= require('. /lib/config .js')

// para chainWebpack

module.exports = function(config, options) {

// inyectar

config.module

.rule ('vue')

.use('vue-filename-injector')

.loader(require.resolve(' . /lib/injector.js')

.options(options)

.after('vue-loader') // De alguna manera, .before() no es el resultado esperado. así que tenemos que andar por aquí

.end()

// Análisis

config.module

.rule('' )

.resourceQuery(new RegExp(`blockType=${blockName}`))

.use('vue-filename-injector-loader' )

.loader(require.resolve('./lib/loader.js')

.end()

}

vue-filename-injector/ lib/config.js:

const defaultPropName = '__source'

const blockName = 'vue-filename-injector'

module.exports = { p>

defaultPropName,

blockName

}

vue-filename-injector/lib/injector.js, fuente parcialmente de vue-loader :

ruta constante = require('ruta')

p>

const loaderUtils = require('loader-utils')

const { blockName, defaultPropName }.= require('./config.js')

módulo. exportaciones = función (contenido /*, mapa, meta */) {

const loaderContext = this

const {

rootContext,

ResourcePath

}= loaderContext

contexto const = rootContext || proceso.cwd()

opciones const = loaderUtils.getOptions( loaderContext) ||

const rawShortFilePath = ruta

.relative(context, ResourcePath)

.replace(/^(\. \..[\/\])+ /, '')

const propName = opciones.propName || defaultPropName

content += `

<${blockName}>

exportar función predeterminada (Componente) {

Component.options.${propName} = ${JSON.stringify(rawShortFilePath.replace(/\/g, '/'))}

}

}

`

devolver contenido

}

vue-filename-injector/lib/loader.js:

module.exports = function(source, map) {

this.callback(null , fuente, mapa)

}

Repositorios relacionados

Vaya a la página de vista previa para ver la apariencia. Hay una palanca en la esquina inferior derecha.

p>

github.com /d2-proyectos?

github.com/d2-projects?

Resumen

Hasta ahora, usar un cargador personalizado para inyectar código parece ser la forma más conveniente sin tener que escribir a mano código duplicado en cada componente.

Dado que vue-cli3 usa chainWebpack y mi conocimiento personal de webpack no es profundo, usaré temporalmente el programa 3.

Lo anterior trata sobre cómo obtener la ruta del código fuente de el archivo único de vue en sí Introducción detallada a la integración. Espero que sea útil para todos. Si tiene alguna pregunta, déjeme un mensaje y le responderé a tiempo. ¡También me gustaría agradecer a todos por su apoyo al sitio web de Script House!