1.
La entrada le indica a webpack que use qué archivo como punto de partida para comenzar a empaquetar, analizar y construir el gráfico de dependencia interna.
2.
La salida indica al paquete web dónde generar los paquetes de recursos empaquetados y cómo nombrarlos.
3.
El paquete web del cargador solo puede comprender archivos JavaScript y JSON, que es la capacidad integrada del paquete web disponible de fábrica. Los cargadores permiten que webpack procese otros tipos de archivos y los convierta en módulos válidos que las aplicaciones pueden usar y agregar al gráfico de dependencia.
4.
ComplementosLos complementos se pueden utilizar para realizar una gama más amplia de tareas. Los complementos van desde la optimización y compresión del empaquetado hasta la redefinición de variables en el entorno.
5. Modo
modo (Modo) indica al paquete web que use la configuración del modo correspondiente.
Le brindamos una introducción detallada a los cinco conceptos centrales de webpack.
El paquete web utiliza el objeto de entrada para buscar, iniciar y construir el paquete. La entrada es el punto de partida de la aplicación. Desde este punto de partida, la aplicación comienza a ejecutarse. Si pasa una matriz, se ejecutará cada elemento de la matriz. El punto de entrada indica qué módulo debe usar el paquete web para comenzar a construir su gráfico de dependencia interna. Después de ingresar el punto de entrada, webpack descubrirá de qué módulos y bibliotecas depende el punto de entrada (directa e indirectamente).
Regla simple: cada página HTML tiene un punto de partida. Aplicación de una sola página (SPA): un punto de entrada, aplicación de varias páginas (MPA): múltiples puntos de entrada.
El valor predeterminado es ./src/index.js
, pero puede especificar un punto (o puntos) de entrada diferentes configurando el atributo entry
en la configuración del paquete web. Por ejemplo:
//Entrada única: cadena module.exports = { entrada: './ruta/a/mi/entrada/archivo.js', }; //Varias entradas--array module.exports = { entrada: ['./src/index.js', './src/add.js'] }; //Varias entradas--object module.exports = { entrada: { inicio: './home.js', acerca de: './about.js', contacto: './contacto.js' } };
Tipo de valor de entrada:
cadena: entrada única, empaquetada para formar un fragmento, y al final solo se generará un archivo de paquete. El nombre predeterminado del fragmento es la
matriz principal: entrada múltiple, solo se generarán todos los archivos de entrada. Forme un fragmento al final. Genere un archivo de paquete y el nombre del fragmento predeterminado es principal. Generalmente solo se usa en la función HMR para hacer que la actualización en caliente de HTML sea
un objeto efectivo: múltiples entradas, tantos fragmentos como claves y tantos archivos de paquete se generan, y cada clave (clave) será el nombre del fragmento. En el tipo de objeto, el valor de cada clave también puede ser una matriz, no solo una cadena
output
indica al paquete web cómo generar y dónde generar su paquete, activo y otros paquetes que empaqueta o cualquier cosa cargada usando el paquete web. . El valor predeterminado del paquete de salida es ./dist/main.js
y otros archivos generados se colocan en la carpeta ./dist
de forma predeterminada.
Puede configurar estos procesos especificando un campo output
en la configuración:
//webpack.config.js ruta constante = requerir('ruta'); módulo.exportaciones = { entrada: './ruta/a/mi/entrada/archivo.js', producción: { ruta: ruta.resolve(__dirname, 'dist'), nombre de archivo: 'mi-primer-webpack.bundle.js', }, };
Podemos decirle al paquete web el nombre del paquete y dónde se genera el paquete a través de output.filename
y output.path
.
2.1.output.filename (nombre de archivo y directorio)
Esta opción determina el directorio y el nombre de cada paquete de salida. Estos paquetes se escribirán en el directorio especificado por la opción output.path
.
Para un único punto入口
, el nombre del archivo será un nombre estático. Sin embargo, al crear varios paquetes a través de múltiples puntos de entrada, división de código o varios complementos, se deben utilizar otros métodos para darle a cada paquete un nombre único.
//Partida simple: módulo.exportaciones = { //... producción: { nombre de archivo: 'js/bundle.js' } }; //Varias entradas: use el nombre de la entrada: módulo.exportaciones = { //... producción: { nombre de archivo: '[nombre].bundle.js' } }; //Varias entradas: use un hash único para generar module.exports = { en cada proceso de compilación //... producción: { nombre de archivo: '[nombre].[hash].bundle.js' } }; ...
2.2. salida.ruta (directorio de archivos)
salida.ruta especifica el directorio de todos los archivos de salida, que es el directorio común para todas las salidas de recursos futuras. La ruta debe ser una ruta absoluta.
módulo.exportaciones = { //... producción: { ruta: ruta.resolve(__dirname, 'dist/assets') } };
2.3.output.publicPath (prefijo de ruta de los recursos referenciados)
publicPath especifica el prefijo de ruta pública introducido por todos los recursos en el archivo html. No afecta la ruta del archivo generado. En cambio, cuando el archivo html introduce varios recursos, publicPath se agrega como prefijo a la ruta de los recursos importados.
Ejemplo:
en la configuración del paquete web generada por vue-cli, el valor de publicPath en el entorno de producción tiene por defecto '/', que es el directorio raíz del directorio actual.
Después del empaquetado, abrimos el archivo html y podemos ver que la ruta del recurso introducida en el archivo html es:
Como puede ver, el símbolo / se agrega delante de la ruta. Cuando abrimos el navegador para acceder al archivo html generado, encontraremos un error. No se puede acceder al recurso y se informa un informe 404. En este momento, el acceso al recurso es similar al siguiente.
Puede que en el servidor sea lo siguiente, pero puede haber problemas para acceder a él.
Podemos cambiar publicPath a una ruta relativa o comentarla directamente.
2.3.1 La diferencia entre ruta y publicPath.
打包后文件在硬盘中的存储位置,是webpack所有文件的输出的路径,必须是绝对路径。比如:输出的js、图片,HtmlWebpackPlugin生成的html文件等,都会存放在以path为基础的目录下。
2.4.output.chunkFilename (nombre del fragmento que no es de entrada)
output.chunkFilename determina el nombre del archivo que no es de entrada. Es decir, además de los fragmentos generados por el archivo de entrada, se nombran los archivos de fragmentos generados por otros archivos.
módulo.exportaciones = { //... producción: { chunkFilename: 'js/[nombre]_chunk.js' //El nombre del fragmento que no es de entrada} };
El paquete web del cargador en sí solo puede empaquetar archivos JavaScript y JSON ( webpack3+和webpack2+
tienen procesamiento integrado de archivos JSON, pero webpack1+并不支持,
necesita introducir json-loader
). Paquete web disponible listo para usar. Webpack en sí no admite el empaquetado de otros tipos de archivos, como CSS, Vue, etc., pero podemos usar varios cargadores para permitir que webpack procese estos tipos de archivos. El cargador puede convertir archivos de diferentes idiomas (como TypeScript) a JavaScript o convertir imágenes en línea en URL de datos. ¡El cargador incluso le permite import
archivos CSS directamente en módulos JavaScript!
Al utilizar diferentes loader
, webpack
tiene la capacidad de llamar scripts o herramientas externos para procesar archivos en diferentes formatos, como analizar y convertir scss a css, o convertir archivos JS de próxima generación (ES6, ES7) a archivos JS compatibles con navegadores modernos. Para el desarrollo de React, los cargadores apropiados pueden convertir archivos JSX utilizados en React en archivos JS.
En la configuración del paquete web, el cargador tiene dos atributos:
atributo test
, que identifica qué archivos se convertirán.
El atributo use
define qué cargador se debe utilizar al realizar la conversión.
include/exclude(可选):
agregue manualmente archivos (carpetas) que deben procesarse o bloquee archivos (carpetas) que no necesitan procesarse
query(可选)
: proporcione opciones de configuración adicionales para los cargadores
// Ejemplo: webpack.config js. ruta constante = requerir('ruta'); módulo.exportaciones = { producción: { nombre de archivo: 'mi-primer-webpack.bundle.js', }, módulo: { normas: [ { prueba: /.txt$/, cargador: 'raw-loader' }, { test: /.css$/, use: ['style-loader', 'css-loader'] } //Si usa varios cargadores, debe usar use ], }, };
En la configuración anterior, el atributo rules
se define para un objeto de módulo separado, que contiene dos atributos requeridos: test
y use
. Esto equivale a decirle al compilador del paquete web que cuando encuentre una ruta analizada como '.txt' en la declaración require()
/ import
, use raw-loader
para convertirla antes de empaquetarla.
Si usa varios cargadores, debe usar use. Los cargadores en la matriz de uso se ejecutan en orden: de derecha a izquierda, en secuencia. Por ejemplo, en el archivo css anterior, primero css-loader compilará el archivo css en JS y lo cargará en el archivo JS. Luego, style-loader creará una etiqueta de estilo e insertará los recursos de estilo en JS en la etiqueta principal.
3.1. CSS-loader
Webpack proporciona dos herramientas para procesar hojas de estilo, css-loader
y style-loader
. Se encargan de diferentes tareas. css-loader
le permite introducir archivos css utilizando un método similar a import
. style-loader
agrega todos los estilos calculados a la página. La combinación de los dos le permite incrustar hojas de estilo en archivos JS empaquetados por webpack. El archivo se puede introducir en el archivo JS.
//Instalar npm install --save-dev style-loader css-loader //Si la versión de css-loader es demasiado alta, la compilación puede fallar. Se recomienda reducir la versión disponible, como [email protected].
//Usar módulo.exportaciones = { ... módulo: { normas: [ { prueba: /(.jsx|.js)$/, usar: { cargador: "babel-cargador" }, excluir: /node_modules/ }, { prueba: /.css$/, //Cómo introducir varios cargadores en el mismo archivo. El orden de acción de los cargadores es que los cargadores posteriores comiencen a actuar en el primer uso: [ { cargador: "cargador de estilos" }, { cargador: "cargador-css" } ] } ] } };
Supongamos que hay un archivo main.css:
cuerpo { fondo: verde; }
Para que el paquete web encuentre el archivo "main.css", lo importamos a "main.js", de la siguiente manera:
//main.js importar Reaccionar desde 'reaccionar'; importar {renderizar} desde 'react-dom'; importar Greeter desde './Greeter'; import './main.css';//Utilice require para importar el archivo css render(<Greeter />, document.getElementById('root'));
Normalmente, css se empaquetará en el mismo archivo que js, no Will empaquetarse como un archivo css separado. Sin embargo, con la configuración adecuada, webpack también puede empaquetar CSS en archivos separados.
se utilizan para convertir ciertos tipos de módulos, mientras que los complementos se pueden usar para realizar una gama más amplia de tareas, que incluyen: optimización de empaquetado, compresión, gestión de recursos, inyección de variables de entorno, etc. El propósito del complemento es resolver otras cosas que el cargador no puede lograr.
Para usar un complemento, debemos instalarlo a través de npm
y luego agregar una instancia del complemento en la propiedad de complementos. Dado que los complementos pueden llevar parámetros/opciones, debe pasar la new
instancia a plugins
en la configuración del paquete web. La mayoría de los complementos se pueden personalizar mediante opciones y puede utilizar el mismo complemento varias veces para diferentes propósitos en un archivo de configuración.
//webpack.config.js const HtmlWebpackPlugin = require('html-webpack-plugin'); // Instalar mediante npm const webpack = require('webpack'); // Se utiliza para acceder a los complementos integrados module.exports = { módulo: { reglas: [{ prueba: /.txt$/, uso: 'raw-loader' }], }, complementos: [nuevo HtmlWebpackPlugin ({ plantilla: './src/index.html' })], };
En el ejemplo anterior, html-webpack-plugin
genera un archivo HTML para la aplicación e inyecta automáticamente todos los paquetes generados.
4.1. Complemento BannerPlugin (agregar declaración de derechos de autor)
A continuación, agregamos un complemento que agrega una declaración de derechos de autor al código empaquetado. Este complemento es un complemento integrado en el paquete web y no es necesario instalarlo.
const paquete web = require('paquete web'); módulo.exportaciones = { ... módulo: { normas: [ { prueba: /(.jsx|.js)$/, usar: { cargador: "babel-cargador" }, excluir: /node_modules/ }, { prueba: /.css$/, usar: [ { cargador: "cargador de estilos" }, { cargador: "cargador-css", opciones: { módulos: verdadero } }, { cargador: "cargador postcss" } ] } ] }, complementos: [ new webpack.BannerPlugin('Wenxuehai todos los derechos reservados, se investigará cualquier reproducción') ], };
4.2. Complemento de reemplazo de módulo en caliente (carga en caliente)
Hot Module Replacement
(HMR) es un complemento muy útil en el paquete web que le permite actualizar y obtener una vista previa automáticamente del efecto modificado en tiempo real después de modificar el código del componente. La carga en caliente es diferente de webpack-dev-server Cuando la aplicación se está ejecutando, el reemplazo en caliente puede ver el efecto de las actualizaciones del código sin actualizar la página, al igual que modificar el estilo dom directamente en el navegador, mientras que webpack-dev-server requiere Actualizar. la página.
(1) Agregue el complemento HMR al archivo de configuración del paquete web;
(2) Agregue el parámetro "hot" al servidor Webpack Dev;
4.2.1. React implementa la carga en caliente
. Los módulos de React pueden usar Babel para implementar la carga en caliente. . Babel tiene un complemento llamado react-transform-hrm
, que permite que HMR funcione correctamente sin configuración adicional del módulo React
install react-transform-hmr
npm install --save-dev babel-plugin-react-transform reaccionar -transform; -hmr
const paquete web = require('paquete web'); módulo.exportaciones = { entrada: __dirname + "/app/main.js", // El único archivo de entrada que se ha mencionado muchas veces salida: { ruta: __dirname + "/público", nombre de archivo: "paquete.js" }, devtool: 'eval-source-map', servidor de desarrollo: { contentBase: "./public",// El directorio donde se encuentra la página cargada por el servidor local HistoryApiFallback: true, // No saltar en línea: true, caliente: cierto }, módulo: { normas: [ { prueba: /(.jsx|.js)$/, usar: { cargador: "babel-cargador" }, excluir: /node_modules/ }, { prueba: /.css$/, usar: [ { cargador: "cargador de estilos" }, { cargador: "cargador-css", opciones: { módulos: verdadero } }, { cargador: "cargador postcss" } ] } ] }, complementos: [ new webpack.BannerPlugin('Derechos de autor, se investigará cualquier reproducción'), nuevo webpack.HotModuleReplacementPlugin() //Complemento de recarga en caliente], };
Configurar Babel
// .babelrc { "presets": ["reaccionar", "env"], "entorno": { "desarrollo": { "complementos": [["reaccionar-transformar", { "transforma": [{ "transformar": "reaccionar-transformar-hmr", "importaciones": ["reaccionar"], "locales": ["módulo"] }] }]] } } }
//Saludador,js importar reaccionar, { Componente } de 'reaccionar' importar estilos desde './main.css' clase Greeter extiende Componente { prestar() { devolver ( <div> <h1> aaaa </h1> </div> ); } } exportar el saludador predeterminado
//main.js importar Reaccionar desde 'reaccionar'; importar { prestar } de 'reaccionar-dom'; importar Greeter desde './greeter.js'; render( < Greeter /> , document.getElementById('root'));
Ahora, si podemos implementar el módulo de carga en caliente, podremos ver el contenido actualizado directamente en el navegador cada vez que guardemos, y el navegador no necesita actualizarse. Actualizar automáticamente.
(A veces no hay ningún efecto, puede ser un problema de versión)
4.3. Complemento ExtractTextWebpackPlugin (extrae css)
De forma predeterminada, webpack no tratará el estilo css como un archivo independiente, sino que también empaquetará el css en un archivo js. y empaquete el archivo js generado. Cuando se procesa, el estilo se insertará en la página en forma de etiqueta de estilo a través de la sintaxis js. Pero en este caso, el archivo del paquete empaquetado puede ser demasiado grande. En este momento, podemos usar el complemento ExtractTextWebpackPlugin para separar el estilo CSS en un archivo CSS.
El complemento ExtractTextWebpackPlugin moverá el *.css al que se hace referencia en el fragmento de entrada (incluido el archivo css importado y el estilo escrito en el archivo vue) a un archivo CSS independiente y separado. ExtractTextPlugin
generará un archivo CSS correspondiente para cada fragmento de entrada, lo que significa que una entrada corresponde a un archivo CSS. Si hay varias entradas, se generarán varios archivos CSS correspondientes respectivamente.
Con el complemento ExtractTextWebpackPlugin, sus estilos ya no estarán incrustados en el paquete JS, sino que se colocarán en un archivo CSS separado (es decir, styles.css
). Si sus archivos de estilo son de mayor tamaño, esto hará que la carga temprana sea más rápida porque el paquete CSS se cargará en paralelo con el paquete JS.
const ExtractTextPlugin = require("extract-text-webpack-plugin"); módulo.exportaciones = { módulo: { normas: [ { prueba: /.css$/, utilizar: ExtractTextPlugin.extract({ respaldo: "cargador de estilos", utilizar: "cargador css" }) } ] }, complementos: [ nuevo ExtractTextPlugin({ nombre de archivo: utils.assetsPath('css/[nombre].[contenthash].css'), //ExtractTextPlugin genera un archivo correspondiente para cada fragmento de entrada, por lo que cuando configura varios fragmentos de entrada, debe usar [nombre], [id ] o [contenthash] // allChunks: true, // Cuando se usa `CommonsChunkPlugin` y hay fragmentos extraídos (de `ExtractTextPlugin.extract`) en el fragmento común, `allChunks` ** debe establecerse en `true`. }), ] }
4.3.1. Opción allChunks (si también se extraen juntos estilos cargados asincrónicamente)
El valor predeterminado de la opción allChunks del complemento ExtractTextWebpackPlugin es falso.
La opción allChunks indica si los estilos cargados de forma asincrónica deben extraerse juntos. Porque de forma predeterminada, incluso si se utiliza el complemento ExtractTextWebpackPlugin, si el estilo o el archivo de estilo se cargan de forma asincrónica, estos estilos no se extraerán en archivos css independientes, sino que aún se empaquetarán en archivos js.
Por lo tanto, allChunks:false
es el valor predeterminado. El valor predeterminado es extraer el código de la entrada, pero el código cargado de forma asincrónica no se extraerá; allChunks:true
es extraer el código de todos los módulos (incluidos los módulos cargados de forma asincrónica). un archivo. Si se utiliza la carga asincrónica de estilos, pero allChunks está configurado en falso, entonces debemos configurar el respaldo de ExtractTextPlugin.extract. fallback
es usar style-loader
para cargar de forma asincrónica cuando el código CSS cargado por el código asincrónico no lo es. extraído. El estilo del componente.
Consulte:
https://github.com/sevenCon/blog-github/blob/master/articles/webpack notas de estudio (2) -Uso de ExtractTextWebpackPlugin.md
https://blog.csdn.net/weixin_41134409/article/ detalles /88416356
Al seleccionar uno de development
, production
o none
para configurar mode
, puede habilitar la optimización integrada del paquete web en el entorno correspondiente. Su valor predeterminado es production
.
módulo.exportaciones = { modo: 'producción', };
Configurar la opción de modo directamente en el archivo de configuración le indicará al paquete web que utilice la optimización incorporada del modo correspondiente. Las opciones de modo incluyen desarrollo, producción y ninguna.
desarrollo: modo de desarrollo, el código empaquetado no se comprimirá y la depuración de código está habilitada.
producción: modo de producción, todo lo contrario.
Configure el modo en desarrollo o producción y webpack establecerá automáticamente el valor de process.env.NODE_ENV. Podemos obtener este valor directamente en cualquier carpeta. Pero si solo configura NODE_ENV
, mode
no se configurará automáticamente. (En el nodo, la variable global proceso representa el proceso del nodo actual. El atributo Process.env contiene información del entorno del usuario. El atributo NODE_ENV no existe en el proceso.env mismo. Generalmente definimos el atributo NODE_ENV nosotros mismos y lo usamos para determinar si es un entorno de producción o un entorno de desarrollo)
(Tenga en cuenta: la opción de modo es nueva en webpack4. Antes de 4, se configuraba con el complemento DefinePlugin. Webpack4 eliminó DefinePlugin)
5.1. se explica en detalle
en el paquete web. Generalmente, el valor de NODE_ENV se configurará en el archivo de configuración. En el proyecto vue generado de forma predeterminada usando vue-cli, la configuración NODE_ENV es la siguiente:
// Bajo el archivo webpack.dev.conf.js, se introduce el archivo dev.env.js new webpack.DefinePlugin({ 'proceso.env': require('../config/dev.env') }),
//module.exports = merge(prodEnv, { en el archivo dev.env.js NODE_ENV: '"desarrollo"' }) //
Bajo el archivo webpack.prod.conf.js, se introduce el archivo prod.env.js const env = require('../config/prod.env') nuevo paquete web.DefinePlugin({ 'proceso.env': env }),
//module.exports = { en el archivo prod.env.js NODE_ENV: '"producción"' }
Como puede ver en lo anterior, en el entorno de desarrollo, el archivo de configuración configura NODE_ENV como 'desarrollo'; en el entorno de producción, el archivo de configuración configura NODE_ENV como 'producción';
Cuando ejecutamos el proyecto, ejecutaremos npm run dev o npm run build. Estos dos comandos utilizan el archivo de configuración del entorno de desarrollo o del entorno de producción para generar el proyecto en ejecución y, en consecuencia, configuramos el valor NODE_ENV correspondiente. el valor NODE_ENV correspondiente se puede obtener en cualquier archivo del proyecto (no necesariamente el archivo de configuración, porque depende de si el archivo de configuración configurado con el valor NODE_ENV ha tenido efecto).
5.2.
El proceso de configuración Process.env.NODE_ENV es una variable global del nodo y el proceso tiene el atributo env, pero no tiene el atributo NODE_ENV. La variable NODE_ENV no está disponible directamente en Process.env, pero se obtiene configurándola. Sin embargo, NODE_ENV
se usa generalmente para definir el tipo de entorno. La función de esta variable es: podemos distinguir el entorno de desarrollo o el entorno de producción al juzgar esta variable.
(1) Los valores de las variables globales se pueden configurar a través del complemento integrado DefinePlugin del paquete web:
new webpack.DefinePlugin({ 'proceso.env.NODE_ENV': JSON.stringify('producción') }),
después de la configuración, puede obtener este valor en el script de ejecución, por ejemplo:
// main.js console.log(process.env.NODE_ENV); //producción
pero este valor no se puede obtener en el archivo de configuración del paquete web webpack.config.js.
(2) Primero descargue el paquete cross-env a través de la
configuración del paquete cross-env:
cnpm i cross-env -D
Configure el archivo package.json:
"build": "cross-env NODE_ENV=test webpack --config webpack.config .js"
En este momento, el valor (process.env.NODE_ENV) se puede obtener en el archivo de configuración, pero no se puede obtener en el script ejecutable. Debe usarse con el complemento DefinePlugin.