Integración de Webpack con Express
Clase 7 de 22 • Curso de Server Side Render con Express
Contenido del curso
Clase 7 de 22 • Curso de Server Side Render con Express
Contenido del curso
Zoila Yaneth Villatoro Garcia
Anthony Quintero
Juan Pablo Celiz
rusbel bermúdez rivera
José María Cuevas Ramírez
Bruno Amadori
Félix Andersson
Marco Elizalde
Imelda Antonia Barrios Morales
Bernardo Ayala Montezuma
Carlos Alfonso Garcia Rivera
Cesar Augusto Morales Lazaro
José Armando Gutiérrez Araujo
Reynaldo Francisco Moreno Briceño
Migrant Cyborg
Diego Pedroza
Jesus Adrian Berrio Valdes
José Enrique Pérez Aquino
Sebastian Matias Pulido
Brandon Ortiz Álvarez
Dilan Santiago Ariza Cañon
Dilan Santiago Ariza Cañon
Luis Gerardo López Hernández
Gerson Montenegro
Óscar Jesús Luna Hernández
Gerson Montenegro
Carlos Enrique Ramírez Flores
Robinson De La Cruz
José Manuel Puicón Rodas
Juan Roa
Andres David Sanchez
Cristian Daniel Jesus Rios
Rafa Anaya
Jose Anibal Garcia Giraldo
Diego Forero
Carlos Gelvez
Carlos Salas Torres
Carlos Acevedo
Wandy Rafael Santana Evangelista
JUAN SILVA
**Error con Dev Middleware **
Con la instalación de:
npm install webpack-dev-middleware webpack-hot-middleware react-hot-loader
Con la siguiente configuración en el package.json
"dependencies": { "@babel/register": "^7.12.1", "dotenv": "^8.2.0", "express": "^4.17.1", "md5": "^2.3.0", "nodemon": "^2.0.6", "prop-types": "^15.7.2", "react": "^16.13.1", "react-dom": "^16.13.1", "react-hot-loader": "^4.13.0", "react-redux": "^7.2.1", "react-router-dom": "^5.2.0", "redux": "^4.0.5", "webpack": "^5.4.0", "webpack-dev-middleware": "^4.0.0", "webpack-hot-middleware": "^2.25.0" }, "devDependencies": { "@babel/core": "^7.12.3", "@babel/plugin-proposal-class-properties": "^7.12.1", "@babel/plugin-transform-runtime": "^7.12.1", "@babel/preset-env": "^7.12.1", "@babel/preset-react": "^7.12.5", "@babel/runtime": "^7.12.5", "babel-eslint": "^10.1.0", "babel-loader": "^8.1.0", "css-loader": "^4.3.0", "eslint": "^7.13.0", "eslint-config-airbnb": "^18.2.1", "eslint-plugin-import": "^2.22.1", "eslint-plugin-jsx-a11y": "^6.4.1", "eslint-plugin-react": "^7.21.5", "file-loader": "^6.2.0", "html-loader": "^1.3.2", "html-webpack-plugin": "^4.5.0", "mini-css-extract-plugin": "^1.3.0", "node-sass": "^4.14.1", "sass-loader": "^10.0.5", "webpack-cli": "^4.2.0", "webpack-dev-server": "^3.11.0" }
Colocar el siguiente codigo en el server.js
if (config.env === 'development') { console.log('Development config'); const webpackConfig = require('../../webpack.config'); const webpackDevMiddleware = require('webpack-dev-middleware'); const webpackHotMiddleware = require('webpack-hot-middleware'); const compiler = webpack(webpackConfig); const { publicPath } = webpackConfig.output; const serverConfig = { serverSideRender: true, publicPath }; app.use(webpackDevMiddleware(compiler, serverConfig)); app.use(webpackHotMiddleware(compiler)); }
Con el codigo en el .babelrc
{ "presets": ["@babel/preset-env", "@babel/preset-react"], "plugins": [ "@babel/plugin-proposal-class-properties", // para que acepte async/ await "@babel/plugin-transform-runtime", "react-hot-loader/babel" ] }
Me sale el siguiente mensaje
Server running on port: 3000 (node:22292) [DEP_WEBPACK_COMPILATION_ASSETS] DeprecationWarning: Compilation.assets will be frozen in future, all modifications are deprecated. BREAKING CHANGE: No more changes should happen to Compilation.assets after sealing the Compilation. Do changes to assets earlier, e. g. in Compilation.hooks.processAssets. Make sure to select an appropriate stage from Compilation.PROCESS_ASSETS_STAGE_*. webpack built 9eb60c02b6e910dda0fd in 4787ms
Al parecer todo funciona bien solamente no se si ese mensaje afecte a futuro si alguien ha logrado solucionarlo agradecería que me ayudaran, gracias de antemano
Gracias, a mi tambien me salia el mismo error y si no es por tu codigo no puedo continuar, te lo agradezco mucho y tambien quedo atento a que me aclaren la duda.
¡Genia! Te súper agradezco, me salvaste :D
La calidad respecto curso anterior, es muy elevada muchas felicidades al profesor
¿Te refieres al curso anterior de la ruta de la Escuela de JavaScript o a una versión previa de este curso?
Casi seguro que se refiere al curso anterior de la ruta :'(
Me gustaría que nos mostraran ejemplos de como funcionaría el proyecto sin estos paquetes para ver que problema estamos solucionando exactamente
Les paso la instalación
npm i webpack-dev-middleware webpack-hot-middleware -D
Se genera un error a la hora de compilar con nodemon
npm run start:dev
Mi solucion
webpack.config.js
<code>const path = require('path'); const webpack = require('webpack'); const HtmlWebPackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = { entry: ['./src/frontend/index.js', 'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=2000&reload=true'], mode: 'development', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js', publicPath: '/', }, resolve: { extensions: ['.js', '.jsx'], }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: "babel-loader", }, }, { test: /\.html$/, use: [ { loader: 'html-loader' } ] }, { test: /\.(s*)css$/, use: [ { loader: MiniCssExtractPlugin.loader, }, 'css-loader', 'sass-loader' ] }, { test: /\.(png|gif|jpg)$/, use: [ { 'loader': 'file-loader', options: { name: 'frontend/assets/[hash].[ext]' } } ] } ] }, devServer: { historyApiFallback: true, }, plugins: [ new webpack.HotModuleReplacementPlugin(), new HtmlWebPackPlugin({ template: './public/index.html', filename: './index.html', }), new MiniCssExtractPlugin({ filename: 'frontend/assets/[name].css', }), ], };
server.js
/* eslint-disable global-require */ import express from 'express'; import dotenv from 'dotenv'; import webpack from 'webpack'; dotenv.config(); const { ENV, PORT } = process.env; const app = express(); if (ENV === 'development') { console.log('Development config'); const webpackConfig = require('../../webpack.config'); const webpackDevMiddleware = require('webpack-dev-middleware') const webpackHotMiddleware = require('webpack-hot-middleware'); const compiler = webpack(webpackConfig); // const serverConfig = { port: PORT, hot: true }; const serverConfig = { serverSideRender: true }; app.use(webpackDevMiddleware(compiler, serverConfig)); app.use(webpackHotMiddleware(compiler)); } app.get('*', (req, res) => { res.send({ hello: 'express' }); }); app.listen(PORT, (err) => { if (err) console.log(err); else console.log('Server running on port 3000'); });
Me salvaste la vida. Me estaba costando entender las otras soluciones propuestas.
Mil gracias.
no se en que momento cambio esa configuración pero gracias.
Para los que no se les actualizan automáticamente los cambios efectuados en los componentes de React agregar el siguiente codigo al final del archivo src/frontend/index.:
if (module.hot) { module.hot.accept(); }
Gracias crack! me ha servido
Gracias, me ayudo tu aporte!
En la documentación de webpack-dev-middleware no aparece hot : true y mucho menos con el port: PORt como una opción valida para inicializar el modulo, en realidad aparece q1ue la forma màs comùn como se inicializa es unicamente con: webpackDevMiddleware(compiler, { publicPath: config.output.publicPath, }) Le saqué este par de valores y compilo sin problemas, pero bueno, habrá que ver más adelante si no rompe algo por haberlos sacado, pero en principio, no debería andarle a nadie con esas opciones para el serverConfig. Si a ti te anda, por favor hazmelo saber.
Documentación
hola por mi parte lo que hoice fue actualizar webpack, webpack-cli, webpack-dev-server y html-webpack-plugin, a la versión actual , y colocando el server.js esto, con la información que configuración que dió Zoila Yaneth Villatoro Garcia en los comentarios.
src/server/server.js
if (ENV === 'development') { console.log('development config'); const webpackConfig = require('../../webpack.config'); const webpackDevMiddleware = require('webpack-dev-middleware'); const webpackHotMiddleware = require('webpack-hot-middleware'); const compiler = webpack(webpackConfig); const serverConfig = {serverSideRender: true, publicPath: webpackConfig.output.publicPath }; app.use(webpackDevMiddleware(compiler, serverConfig)); app.use(webpackHotMiddleware(compiler)); }```
El profe usa la version 3.7.2 y la ultima que hay actalmente 4.1.0 otra cosa mas, es mejor instalar estas dependecias como desarollo
Integración de Webpack con Express
Para poder integrar webpack con express debemos instalar las siguientes dependencias
npm install webpack-dev-middleware webpack-hot-middleware react-hot-loader
Luego debemos agregar el código siguiente a el archivo de configuración del servidor.
import webpack from 'webpack'; if (process.env.ENV === 'development') { //Verifying if its on dev mode // requiring all the dependencies const webpackConfig = require('../../webpack.config'); const webpackDevMiddleware = require('webpack-dev-middleware'); const webpackHotMiddleware = require('webpack-hot-middleware'); //creating a webpack compiler with our configurations const compiler = webpack(webpackConfig); //executing webpack with its configurations const serverConfig = { port: process.env.PORT, hot: true }; //declaring the port and enabling hot reload in dev server //adding the middlewares into the server app.use(webpackDevMiddleware(compiler, serverConfig)); //Middleware to compile all the files and put it on the server app.use(webpackHotMiddleware(compiler)); //Middleware to enable hot reload }
Después debemos agregar unas líneas extras en nuestra configuración de webpack
Primero agregamos un nuevo plugin:
const webpack = require('webpack') plugins: [ new webpack.HotModuleReplacementPlugin(), ]
Luego, alteramos nuestro entry principal y agregamos en que modo se encontrara el servidor:
module.exports = { entry: ['./src/frontend/index.js', 'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=2000&reload=true'], mode: 'development' }
Con esto habilitamos el hot reload en webpack y le mencionamos explícitamente que nos encontramos en un entorno de desarrollo
Para finalizar, alteramos el archivo .babelrc agregando la siguiente linea
{ "plugins": ["react-hot-loader/babel"] }
Gracias! tu comentario me ayudo a solucionar el error de validaction schema.
¿Diferencias entre import y require?
"La principal diferencia entre require y import, es que require escaneará automáticamente node_modules para encontrar módulos, pero import, que viene de ES6, no ."
"La mayoría de las personas usan babel para compilar import y export, lo que hace que import actúe igual que require.
La versión futura de Node.js podría admitir import en sí misma (en realidad, la versión experimental ya lo hace ), y a juzgar por las notas de Node.js, import no admitirá node_modules, se basa en ES6 y debe especificar la ruta del módulo.
Por lo tanto, le sugiero que no use import con babel, pero esta función aún no está confirmada, podría admitir node_modules en el futuro, ¿quién lo sabría?
Como referencia, a continuación se muestra un ejemplo de cómo Babel puede convertir la sintaxis import de ES6 en la sintaxis require de CommonJS."
Textualmente desde
Lo coloque textualmente porque siento que es bastante claro, mira el foro, te va a servir en mas preguntas :)
entry points
entry: ['./src/frontend/index.js', 'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=2000&reload=true'],
Si como yo tuvieron este error:
TypeError: Cannot add property htmlWebpackPluginAlterChunks, object is not extensible
Disparado justo en esta línea:
app.use(webpackDevMiddleware(compiler, webpackServerConfig));
Es porque estamos usando la última versión de webpack, que en este momento es la 5.2.0, cuando el profesor usa la 4.41.5. Para solucionar este problema, lo que debemos hacer es actualizar el paquete html-webpack-plugin a su última versión, que en mi caso es la 4.5.0.
gracias por tu respuesta y podrias compartirme como quedo tu objeto de serverConfig
claro, @oluna93, aunque fue el mismo del profesor:
const webpackServerConfig = { port: PORT, hot: true };
Y PORT viene desde las variables de entorno:
const { ENV, PORT } = process.env;
Los instalamos como dependencias de desarrollo
npm i webpack-hot-middleware webpack-dev-middleware -D
Instalamos la dependencia de react-hot-loader
react-hot-loader
npm i react-hot-loader -S
Esas dependencias deben estar como producción, no como dependencias de desarrollo, si no saldrá el mismo aviso que le sale al profesor con la dependencia de webpack
Si tienen un error parecido a este:
Cannot find module 'react-hot-loader/babel
Instalen de la siguiente manera:
npm install react-hot-loader --save-dev
¡Gracias!
Esa dependencia deben estar como producción, no como dependencias de desarrollo!
Buenas, ah que se refiero cuando dice "que todo nuestro sitio web haga un hotModulePlacement" en el minuto 4:10 aprox... gracias
Hot-Module-Replacement, significa remplazo de modulos en caliente, se llama así porque su función es detectar cambios y actualizar nuestra aplicación pero sin recargar toda la página, es decir, solo actualiza el componente que recibió algun cambio.
No termino de enteder la utilidad que brinda el webpack dev middleware realmente, y no termino de entenderlo ni en documentación :/, algún heroe que me lo explique? :D
Hola, se usa principalmente para poder tener el Hot Module Replacement que hace que se recargue de forma automática el módulo de react/vue/svelte que editas. El dev middleware no escribe los archivos transpilados de JSX a js en el disco si no que los mantiene en memoria. Espero que con esto te quede más claro.
LA version de webpack influye, pues estoy usando la version 5 y me mandaba un error pero al pasarlo a la version 4 este error se fue
Como podria hacer esta configuracion en la version 5
compilation.hooks.htmlWebpackPluginAlterChunks = new SyncWaterfallHook(['chunks', 'objectWithPluginRef']); ^ TypeError: Cannot add property htmlWebpackPluginAlterChunks, object is not extensible
Si alguien tiene el siguiente error: ValidationError: Invalid options object. Dev Middleware has been initialized using an options object that does not match the API schema. options has an unknown property ‘hot’. These properties are valid: object { mimeTypes?, writeToDisk?, methods?, headers?, publicPath?, serverSideRender?, outputFileSystem?, index? } ValidationError: Invalid options object. Dev Middleware has been initialized using an options object that does not match the API schema.
En el archivo server.js remuevan las propiedades port y hot y agregen serverSideRender:
const serverConfig = { serverSideRender: true };
Es un verdadero problema las versiones de cada librería. Deberían tomar en cuenta que para el momento en que algunos tomamos este curso habrá nuevas versiones y esta configuración mostrada en clase no funcionará!
Hola Devs: Aqui tienen:
'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=2000&reload=true'
npm install webpack-dev-middleware webpack-hot-middleware --dev