plugin minicssextractplugin mini extracttextplugin webpack webpack-dev-server

minicssextractplugin - webpack min css



Reemplazo de módulo caliente de webpack: css sin actualización (5)

Hasta ahora he estado usando livereload para que cada vez que cambie JS o plantillas, la página se actualice, y cuando cambie CSS, hotswap el nuevo CSS sin una actualización.

Estoy probando el paquete web ahora y casi llegué al mismo comportamiento, con una excepción: cuando el CSS cambia, se actualiza toda la ventana. ¿Es posible hacer que hotswap el CSS sin actualización?

Config hasta ahora:

var webpackConfig = { entry: ["webpack/hot/dev-server", __dirname + ''/app/scripts/app.js''], debug: true, output: { path: __dirname + ''/app'', filename: ''scripts/build.js'' }, devtool: ''source-map'', plugins: [ new webpack.HotModuleReplacementPlugin(), new htmlWebpackPlugin({ template: __dirname + ''/app/index.html'', inject: ''body'', hash: true, config: config }), new webpack.ProvidePlugin({ ''angular'': ''angular'' }), new ExtractTextPlugin("styles.css") ], module: { loaders: [ { test: //.scss$/, loader: "style!css!sass?includePaths[]=" + __dirname + "/app/bower_components/compass-mixins/lib&includePaths[]=" + __dirname + ''/instance/sth/styles&includePaths[]='' + __dirname + ''/app/scripts'' } ] } };


Ahora es posible usar angular2, webpack con reemplazo de módulo en caliente, sasscemaps sass y css cargados externamente. Me tomó días jugarlo, ¡pero lo tengo funcionando!

Las dependencias son style-loader , css-loader y sass-loader (si se usa sass, si no, se puede eliminar el sass loader)

Utilizo ExtractTextPlugin para el modo de producción para emitir archivos .css reales.

NOTA: Para que esto funcione, no uso la propiedad stylesUrl, en lugar de eso, importo el archivo .scss fuera del decorador de @Component para que los estilos se carguen en el contexto global, en lugar del ámbito por componente.

Esta configuración permite el reemplazo de Hot Module con archivos SCSS utilizando el servidor webpack dev, y extracttextplugin para que el modo de producción emita archivos .css reales.

Aquí está mi configuración de trabajo

{ test: //.(scss)$/, use: isDevServer ? [ { loader: ''style-loader'', }, { loader: ''css-loader'', options: { sourceMap: true } }, { loader: ''postcss-loader'', options: { postcss: [AutoPrefixer(autoPrefixerOptions)], sourceMap: true } }, { loader: ''sass-loader'', options: { sourceMap: true } }, { loader: ''sass-resources-loader'', options: { resources: [ ''./src/assets/styles/variables.scss'', ''./src/assets/styles/mixins.scss''] } }, /** * The sass-vars-loader will convert the ''vars'' property or any module.exports of * a .JS or .JSON file into valid SASS and append to the beginning of each * .scss file loaded. * * See: https://github.com/epegzz/sass-vars-loader */ { loader: ''@epegzz/sass-vars-loader?'', options: querystring.stringify({ vars: JSON.stringify({ susyIsDevServer: susyIsDevServer }) }) }] : // dev mode ExtractTextPlugin.extract({ fallback: "css-loader", use: [ { loader: ''css-loader'', options: { sourceMap: true } }, { loader: ''postcss-loader'', options: { postcss: [AutoPrefixer(autoPrefixerOptions)], sourceMap: true } }, { loader: ''sass-loader'', options: { sourceMap: true } }, { loader: ''sass-resources-loader'', options: { resources: [ ''./src/assets/styles/variables.scss'', ''./src/assets/styles/mixins.scss''] } }, { loader: ''@epegzz/sass-vars-loader?'', options: querystring.stringify({ vars: JSON.stringify({ susyIsDevServer: susyIsDevServer }) // // Or use ''files" object to specify vars in an external .js or .json file // files: [ // path.resolve(helpers.paths.appRoot + ''/assets/styles/sass-js-variables.js'') // ], }) }], publicPath: ''/'' // ''string'' override the publicPath setting for this loader }) },

Luego, en su componente, por ejemplo, app.component.ts , necesitará su archivo app.style.scss FUERA del decorador @Component .

Ese es el truco. Esto no funcionará si carga estilos de forma angular con stylesUrl . Si lo hace de esta manera, podrá cargar hojas de estilo .css perezosa para los componentes que se cargan de forma perezosa, lo que hace que el tiempo de carga inicial sea aún más rápido.

app.component.css

/* * THIS IS WHERE WE REQUIRE CSS/SCSS FILES THAT THIS COMPONENT NEEDS * * Function: To enable so-called "Lazy Loading" CSS/SCSS files "on demand" as the app views need them. * Do NOT add styles the "Angular2 Way" in the @Component decorator ("styles" and "styleUrls" properties) */ import ''./app.style.scss'' /** * AppComponent Component * Top Level Component */ @Component({ selector: ''body'', encapsulation: ViewEncapsulation.None, host: { ''[class.authenticated]'': ''appState.state.isAuthenticated'' }, templateUrl: ''./app.template.html'' })

No he tenido problemas para ejecutar esta configuración. ¡Aqui tienes!

Actualizado el 08/2017: configuración mejorada para los requisitos de esquema del paquete web 3+, y para trabajar con la compilación de Angular 4 AOT.


Aunque ExtractTextPlugin dice "Sin reemplazo de módulo en caliente" en su sección README , lo arreglé actualizando manualmente los archivos CSS a través de la API BrowserSync .

Usé gaze para escuchar cualquier cambio en mis archivos CSS, y luego usé BrowserSync para actualizarlos.

npm install gaze

También puede hacerlo fácilmente editando su script de compilación con algo de lo siguiente:

const { Gaze } = require(''gaze''); // Your own BrowserSync init browserSync.init({ ... }, resolve); // Create a watcher: // You can watch/reload specific files according to your build/project structure const gaze = new Gaze(''**/*.css''); gaze.on(''all'', () => bs.reload(''*.css''));

Espero que ayude.


En realidad, hay una manera simple de hacer esto. Estoy usando sass-loader con el complemento de texto extra que produce archivos css.

Lo que tienes que hacer es agregar ID a tu css include

<link id="js-style" type="text/css" rel="stylesheet" href="/static/main.css">

Ahora, debe asegurarse de que, cuando ocurra HMR, actualice la URL con la versión / marca de tiempo actual. Puedes hacerlo de esta manera:

import ''../style/main.scss'' if (module.hot) { module.hot.accept(''../style/main.scss'', () => { const baseStyle = window.document.getElementById(''js-style'') baseStyle.setAttribute(''href'', ''/static/main.css?v='' + new Date().valueOf) }) }

Así que cada vez que css cambie, arreglaremos la url de css include para recargarla.


Esta es una de las desventajas de usar ExtractTextPlugin como se indica en el proyecto README . Puedes resolver el problema dividiendo tu configuración. Es decir. Tiene configuración separada para desarrollo sin ella y una para producción con ella.


Puede usar ''css-hot-loader'' para habilitar HMR para su css extraído. Funciona perfectamente para mí.