Heim >Web-Frontend >js-Tutorial >So verwalten Sie CSS und andere Ressourcen in Webpack und SPA
In diesem Artikel werden hauptsächlich die Methoden zur Verwaltung von CSS und anderen Ressourcen in der Webpack- und SPA-Praxis vorgestellt. Der Herausgeber findet ihn recht gut, daher werde ich ihn jetzt mit Ihnen teilen und als Referenz verwenden. Folgen wir dem Editor und werfen wir einen Blick darauf.
Im vorherigen Artikel wurde beschrieben, wie man mit Webpack eine stabile Entwicklungsumgebung erstellt, die lokale Dienste, automatische Aktualisierung, Modul-Hot-Replacement und das Schreiben von JavaScript mit ES6 unterstützt webpack Wie man mit einem weiteren Element der drei Hauptelemente von HTML-Anwendungen umgeht – CSS und andere Ressourcen wie Bilder, Schriftartdateien oder Datenkonfigurationsdateien.
Vorwort
Wenn wir lernen, Webpack zu verwenden, müssen wir verstehen, dass es unabhängig davon, wie es entworfen ist, was sein Funktionsprinzip und Prozess ist, das Grundlegende ist Prozesse sind HTML-HTML-Tags, JavaScript, CSS, Bilder und andere Ressourcen im Dokument, und das endgültige Verarbeitungsergebnis muss immer noch ein HTML-Dokument sein, einschließlich DOM, JavaScript, CSS, und es gibt drei Möglichkeiten, wie CSS im Dokument vorhanden sein kann: Inline-Stil, Inline Die Verwendung von Stilen, externen Linkstilen und Inline-Stilen ist seit langem veraltet, daher gibt es für Webpack nur zwei Möglichkeiten, CSS zu verarbeiten:
Inline-Stile: Verwenden Sie die c9ccee2e6ea535a969eb3f532ad9fe89-Tag im HTML-Dokument Einbetten von Stilen in;
Installieren
npm install --save-dev style-loader css-loaderKonfiguration
Fügen Sie die folgende Konfiguration in der Modulladeoption der Webpack-Konfigurationsdatei hinzu:
module: { loaders: [ { test: /\.css$/, loader: "style-loader!css-loader" } ] }
Um die Verwendung von Referenzpfaden zu erleichtern, können Sie natürlich auch den Pfadfragment-Alias konfigurieren:
alias: {
styles: path.resolve(__dirname, 'src/styles/')
}
Zu diesem Zeitpunkt entspricht
import 'styles/index.css';
import '../src/styles/indx.css';
zum Konfigurieren verwendet haben und eine index.css-Datei im Styles-Verzeichnis erstellen, können wir das CSS jetzt direkt in das einfügen JavaScript-Datei: import 'styles/index.css'; oder require ('styles/index.css');
CSS-Inhalt ist wie folgt:
html, body {
width: 100%;
height: 100%;
}
.container {
color: red;
}
Die Seite wird wie in gezeigt angezeigt das Bild:
Inline-Stil
Wie bereits erwähnt, gibt es für Webpack zwei Möglichkeiten, CSS zu verarbeiten Fügen Sie den Inline-Stil c9ccee2e6ea535a969eb3f532ad9fe89 dynamisch in das Tag 93f0f5c25f18dab9d176bd4f6de5d30e ein. Diese Methode ist auch die Standardverarbeitungsmethode von Webpack. Sie müssen lediglich den folgenden Loader konfigurieren Loader-Parsing-Reihenfolge
Wie im obigen Code gezeigt, unabhängig davon, ob es sich um eine Zeichenkettensyntax oder eine Array-Syntax
handelt, gelten die Webpack-Parsingregeln von rechts nach links, wobei der Loader analysiert und ausgeführt wird Die Ausgabe der vorherigen Loader-Verarbeitung ist die Eingabe der nächsten Loader-Verarbeitung. Bis die endgültige Loader-Verarbeitung hier abgeschlossen ist, ruft Webpack zuerst den CSS-Loader-Loader auf, um die CSS-Datei zu verarbeiten Ergebnis an den Style-Loader-Loader, und der Style-Loader akzeptiert die Eingabe und setzt die Verarbeitung fort.CSS-LOADER
Wir haben wiederholt betont, dass Webpack nur JavaScript verarbeiten kann, sodass Sie für andere Ressourcen wie CSS oder Bilder einen Loader zum Konvertieren verwenden müssen und an das JavaScript-Modul ausgeben, Webpack kann mit der Verarbeitung fortfahren.style-loader!css-loader
Die Funktion des CSS-Loader-Loaders besteht darin, uns bei der Referenzierung von CSS-Dateien in JavaScript-Dateien zu unterstützen, z. B. mithilfe von JavaScript-Modulen, z. B. require ('./index.css'), damit Sie sich seine Funktion vorstellen können as Die Datei wird in ein JavaScript-Modul konvertiert, sodass wir durch Einführung des JavaScript-Moduls direkt darauf verweisen können. ['style-loader', 'css-loader']
Parameter
css-loader hat zwei allgemeine Parameter: modules: {boolean} gibt an, ob CSS-Module verwendet werden sollen (Zum Beispiel: local und :global legen lokale oder globale Stilregeln fest), der Standardwert ist false, aktivieren Sie Einstellungen wie css-loader?modules;importLoaders: {number} gibt CSS an -Loader zum Laden Die Anzahl der Loader, die vor dem Loader verwendet werden, der Standardwert ist 0, eingestellt wie css-loader?importLoaders=1; Wie Webpack CSS-Dateien verarbeitet, müssen diese letztendlich auf der Seite ausgegeben werden, bevor die CSS-Regeln tatsächlich ausgeführt werden können Der Style-Loader-Loader fügt CSS inline in das Seitendokument ein, d. Loader fügt ein c9ccee2e6ea535a969eb3f532ad9fe89-Tag in das 93f0f5c25f18dab9d176bd4f6de5d30e-Tag ein, und die Stilregeln im Tag sind der Eingabeinhalt, wie im folgenden Beispiel gezeigt:
外链样式
当然,我们并不总是希望所有样式都以内联方式存在页面中,很多时候我们也希望通过外链方式使用样式表,特别是样式规则较多的时候,webpack开发者们当然考虑了这样的需求。
webpack提供的style-loader
加载器默认是以内联方式将样式插入文档,我们需要使用webpack extract-text-webpack-plugin
插件以实现输出单独CSS文件。
EXTRACT TEXT PLUGIN
安装
首先安装该插件:
npm install --save-dev extract-text-webpack-plugin
配置
然后添加如下配置:
var ExtractTextPlugin = require('extract-text-webpack-plugin'); ... module: { loaders: [ { test: /\.css$/, exclude: /node_modules/, // 老版本 loader: ExtractTextPlugin.extract('style-loader', 'css-loader') loader: ExtractTextPlugin.extract({ fallback:'style-loader', use: 'css-loader' }) } ] }, plugins: [ // 生成独立css文件 new ExtractTextPlugin({ filename: 'css/[name].css' }) ]
运行webpack命令,我们会看到在dist/css/文件夹下生成相应的CSS文件。
参数
filename {String | Function}
Extract Text Plugin为每个入口生成一个CSS文件,所以对于多入口项目需要指定filename参数[name]或[id]或[contenthash]生成唯一识别文件名;
disable {Boolean}
禁用此插件;
allChunks {Boolean}
allChunks: true;时指定从所有模块中抽取CSS输出至单独CSS文件,包括异步引入的额外模块;此插件默认是只抽取初始模块内引入的CSS;
extract方法
该方法可以以参数指定加载器,然后接受该加载器的输出,进行处理。需要在加载器和插件配置中同时声明相关配置,才能实现效果;在加载器配置中调用其extract方法传入通常以下两个参数:
1. use: 将CSS转换成模块的加载器;
2. fallback: 对于不被抽取输出至单独CSS文件的CSS模块使用的加载器,上例中`style-loader`即说明以内联方式使用,该加载器通常在`allChunks: false`时处理额外的模块;
FILENAME与OUTPUT
在上一篇介绍了输出文件配置output相关内容,其中:
output.path是webpack处理文件后输出的路径,对于CSS文件输出依然适用,即CSS文件也将输出至该目录;
output.publicPath是指浏览器访问资源时的相对基础路径,规则是: output.publicPath + output.filename;
你可以看到在本系列文章实例中filename都添加了前缀目录,如css和scripts,你可能看到很多项目是不添加的,但文件入口较多时建议分类型目录输出,而且需要记得在浏览器访问资源时也需要添加该目录层级。
CSS预处理器
通常在开发较复杂的应用时,我们都会选择一种CSS的强化辅助工具,以更高效,更方便的使用CSS开发应用样式,这些拓展工具就是所说的CSS预处理器.
CSS预处理器(preprocessors)在CSS语法的基础上增加了变量 (variables)、嵌套 (nested rules)、混合 (mixins)、导入 (inline imports) 等高级功能,令CSS更加强大与优雅,有助于更好地组织管理样式文件,以及更高效地开发项目。
目前最常见的CSS预处理器有LESS,SASS,Stylus,个人用过的是前两种,使用SASS的还是居多。
SASS
安装
npm install --save-dev sass-loader
安装sass-loader以后会发现,package.json中多了一个node-sass依赖,这是使用SASS必须的。
配置
然后添加以下配置:
{ test: /\.s[ac]ss$/, exclude: /node_modules/, loader: 'style-loader!css-loader!sass-loader' }
如上,配置中传递了三个加载器,相对于前文处理CSS文件的加载器,在最后面多了一个sass-loader,首先加载sass-loader加载器处理SASS文件成CSS代码,然后继续按照前文描述流程处理CSS文件。
EXTRACT TEXT PLUGIN
和处理CSS文件一样,上述配置最终通过style-loader将转换后的CSS代码内联到页面,我们需要使用Extract Text Plugin生成单独CSS文件,以外链方式引用:
{ test: /\.s[ac]ss$/, exclude: /node_modules/, loader: ExtractTextPlugin.extract({ fallback:'style-loader', use: [ 'css-loader', 'sass-loader' ] }) } ... // 生成独立css文件 new ExtractTextPlugin({ filename: 'css/[name].css' })
CSS后处理器
前面讲到CSS预处理器,如SASS,他们提供对CSS的拓展,包括语法拓展,高级特性拓展,如嵌套,变量,自动处理添加属性前缀等,使得我们可以以其定义的语法与模板方式更高效的编写CSS,然而这些预处理器都是另外对CSS进行拓展,各自定义了语法和模板,其处理流程是对代码进行解析处理,然后转换成CSS代码。
不同预处理器有各自的定义和规范,假如你需要从LESS转到SASS,源代码转换成本和学习成本颇高,而接下来要介绍的CSS后处理器并没有这个问题。
不同于预处理器预定义好一个语法和模板,然后对按照该语法和模板编写的代码进行处理转换成CSS,其输入是自定义语法文件,输出是CSS代码;后处理器(postprocessor)是对原生CSS代码根据配置进行处理,其输入输出依然是CSS代码。
POSTCSS
现在最受欢迎的CSS后处理器,就是postcss:
PostCSS is a tool for transforming styles with JS plugins. These plugins can lint your CSS, support variables and mixins, transpile future CSS syntax, inline images, and more.
PostCSS是一个使用Js插件转换样式的根据,插件支持拓展CSS,如变量,混合,CSS属性语法兼容,行内图片等等功能。
特性
不同于SASS提供一个功能性拓展工具,postcss更多的是提供一个CSS高效开发工具解决方式,其本身只包含CSS解析器只能将CSS处理成一棵抽象语法树(AST),同时提供一个丰富的CSS节点树API,可以对语法树进行操作,另外它有一个高拓展性的插件系统支持我们通过引入不同插件对CSS进行处理,一个插件的输出还可以是下一个插件的输入,更值得一提的是,这些插件都是JavaScript插件,前端开发者们很容易就能根据项目需求定制自己的插件,所以可以总结几点一以下特性:
postcss只处理CSS,概念简洁;
提供高拓展性的插件系统支持按需引入不同插件,实现不同处理;
使用JavaScript插件,开发者可以很方便定制项目插件;
提供CSS节点树API,可以高效的进行CSS处理;
安装
在webpack中使用,需要先安装对应加载器:
npm install --save-dev postcss-loader
插件
postcss目前有200+插件,足够满足绝大部分项目开发需求,可以查看postcss插件,我们介绍几个主要使用的插件。
Autoprefixer
回顾一下在预处理器中,如果我们需要为CSS代码添加属性前缀,需要这么实现呢?对于Sass,我们通常使用mixin,即混合宏,处理CSS属性前缀,如:
// 定义 @mixin prefix-animation($animation-name){ animation:$animation-name; -webkit-animation:$animation-name; } // 使用 body{ @include prefix-animation(loading .5s linear infinite); }
如上,我们需要按照定义的语法和模板:先定义一个mixin,然后通过@include方式使用,最后才能输出添加前缀的CSS代码,当代码越来越多时,我们需要定义的mixin也会越来越多,而且不同预处理器定义的语法和模板都有差异,学习成本、转换成本都很可能令人难以接受。
那么postcss插件怎么处理的呢?postcss提供了Autoprefixer插件处理CSS属性前缀:
Autoprefixer插件基于Can I Use的数据,对CSS规则进行前缀处理。
安装
首先还是要安装Autoprefixer:
npm install --save-dev autoprefixer
配置
添加如下配置:
module: { loaders: [ { test: /\.css$/, exclude: /node_modules/, loaders: [ 'style-loader', 'css-loader', { loader: 'postcss-loader', options: { plugins: [ require('autoprefixer')({ browsers: ['last 2 versions'] }) ] } } ] } ] }
如上,我们知道postcss是一个样式开发解决方案,其特定功能需要引入插件实现,上例中在指定postcss-loader加载器时为其设置了插件配置autoprefixer;当然webpack还支持直接设置一个postcss配置文件,然后在项目根目录创建postcss.config.js配置文件,内容格式如下:
module.exports = { plugins: [ require('autoprefixer')({ browsers: ['last 2 versions'] }) // or just require('autoprefixer') ] }
使用autoprefixer插件时可选传入browsers参数,可以设置添加前缀的适配范围,详细可查阅browsers配置说明。
混合使用CSS预处理器与后处理器 – PreCSS
也许你迫不及待想在项目中引入postcss,又希望能继续使用CSS预处理器语法,而且需要保证以前按照某预处理器预定语法和模板(如SASS)编写的源代码继续稳定使用,不需要太多的迁移和学习成本,可以做到吗?当然可以,可以使用预处理器PreCSS插件包,另外我们需要安装一个postcss的scss解析器,因为postcss默认只包含一个CSS解析器,postcss配置文件更新如下:
module.exports = { parser: require('postcss-scss'), plugins: [ require('autoprefixer')({ browsers: ['last 2 versions'] }), require('precss') ] }
webpack配置文件更新配置:
modules: { loaders: [ { test: /\.s?[ac]ss$/, exclude: /node_modules/, // or 内联方式 loader: 'style-loader!css-loader!postcss-loader' loader: ExtractTextPlugin.extract({ fallback:'style-loader', use: [ 'css-loader', 'postcss-loader' ] }) } ] }
可以看到文件匹配规则,修改为/\.s?[ac]ss$/,可以匹配包括.sass, .scss, .css样式文件;在css-loader加载器之前添加了postcss-loader加载器(webpack加载器解析顺序为从右至左)。
当然你可以不使用precss,依然使用sass-loader,则只需要修改配置:
loader: 'style-loader!css-loader!postcss-loader!sass-loader'
对于如下SCSS代码:
$column: 200px; .menu { display: flex; width: calc(4 * $column); }
转换生成如下CSS代码:
.menu { display: -webkit-box; display: -ms-flexbox; display: flex; width: calc(4 * 200px); }
处理图片与字体文件
对于一个应用而言,除了需要开发HTML、CSS、JavaScript,通常还好使用到图片,字体文件,配置文件等诸多资源,那么前端工程化流程也就必然需要对这些资源进行处理与优化,最典型的说处理图片和字体文件。
在Grunt或Gulp中,我们对图片和字体文件的处理通常是将其从源目录压缩优化处理后输出至输出目录,通常是以文件目录整体进行处理,每次构建时,对所有资源,包括未使用的图片均进行处理,效率是有局限的;而webpack中一切资源文件都可以处理成模块,然后在编译时管理模块依赖,可以做到只处理存在依赖的资源(即,使用了的资源)。
图片与字体
当我们在Js模块中引入CSS文件时,其中样式规则中的背景图片,字体文件如何处理呢?webpack只能管理模块化的东西,需要将其模块化,然后使用webpack管理依赖,webpack提供了file-loader加载器:
File Loader
Instructs webpack to emit the required object as file and to return its public url.
通知webpack将引入的对象输出为文件并返回其公开资源路径。
配置
module: { loaders: [ { test: /\.(png|svg|jpe?g|gif)$/, loader: [ 'file-loader' ] } ] }
说明
当我们在js文件中import Image from '../images/test.png'或在CSS文件中url('../images/test.png')时,file-loader将处理该图片并在output.path目录下输出文件,然后将../images/test.png路径替换成该输出文件路径。
注,对于html中引用的图片,需要使用[html-loader]加载器处理(http://npm.taobao.org/package/html-loader)。
参数
emitFile: 是否输出文件;
name: 指定输出文件的文件名,有几个可用内置变量:
[name]: 引用资源的名称;
[path]: 引用资源的相对路径;
[ext]: 资源拓展名;
[hash]: 资源内容的hash值,默认使用md5算法计算得到,可以指定长度值,如[hash:7]表示返回hash值前7个字符;
[hashType:hash:digestType:length]: 指定hash值计算算法类型和摘要类型,及摘要长度,如sha512:hash:base64:7表示使用sha512加密算法计算hash值并且返回7个字符的base64编码字符
实例
在配置时可以指定参数:file-loader?name=[name].[ext]?[hash:8]
或者以配置对象方式:
{ test: /\.(png|svg|jpe?g|gif)$/, loaders: [ // 'file-loader?name=[path][name].[ext]?[hash:8]' { loader: 'file-loader', query: { name: '[path][name].[ext]?[hash:8]' } } ] }
对于CSS源代码:
.wrapper { font-size: 18px; background: url('../images/test.png') no-repeat 0 0; }
输出CSS代码如下:
.wrapper { font-size: 18px; background: url(assets/images/test.png?59427321) no-repeat 0 0; }
assets为output.publicPath指定值,images/test.png?59427321为配置文件中指定的name模板,在output.path目录下输出images/test.png,区别是,不会携带?后的参数。
另外,你也可以在js模板中这样使用:
<img src={imgSrc} /> ... import imgSrc from 'path/xxx.png';
Url Loader
你可能会发现前面并没有安装file-loader,因为有更好用的加载器url-loader,url-loader加载器是file-loader的升级版,他们唯一的不同之处在于:
url-loader可以通过limit参数指定一个尺寸值,加载器会对小于该值的资源处理返回一个Data URL,以base64的方式嵌入HTML或CSS,如url-loader?limit=65000;对于大于该尺寸的资源将使用file-loader处理并且传递所有参数。
mimetype
还可以设置mimetype对处理文件进行过滤,如url-loader?mimetype=image/png将只处理png类型的资源。
安装
npm install --save-dev url-loader
配置
该加载器对于图片和字体文件资源都适用:
{ test: /\.(png|svg|jpe?g|gif)$/, loaders: [ // 'url-loader?name=[path][name].[ext]?[hash:8]' { loader: 'url-loader', query: { limit: 6000, name: '[path][name].[ext]?[hash:8]' } } ] }, { test: /\.(woff|woff2|eot|ttf|otf)$/, loaders: [{ loader: 'url-loader', query: { limit: 10000, name: '[path][name].[ext]?[hash:8]' } }] }
资源优化
完成以上配置后,已经可以在项目中很方便的引用各自资源了,但是通常我们还需要对图片字体等文件进行压缩优化处理,如Grunt中使用的imagemin插件一样压缩资源,webpack则提供了相关加载器img-loader。
安装
npm install --save-dev img-loader
配置
{ test: /\.(jpe?g|png|gif|svg)$/i, loaders: [ 'url-loader?name=[path][name].[ext]?[hash:8]', { loader: 'img-loader', options: { // 根据环境判断是否启用资源压缩 enabled: process.env.NODE_ENV === 'production', gifsicle: { interlaced: false // 替换使用渐进式渲染 }, mozjpeg: { progressive: true, // 创建基准jpeg文件 }, optipng: { optimizationLevel: 4, // 优化级别,0-7,值越大,压缩越多 }, pngquant: { quality: '75-90', // 压缩质量,0-100,值越高,质量越高 speed: 3 // 执行速度,0-10,速度过高质量受损,不建议过高 }, svgo: { plugins: [ { removeTitle: true }, // 去除标题信息 { convertPathData: false } // 转换路径为更短的相对或决定路径 ] } } } ] }
以上为常见使用配置,更多详细配置信息请查看对应说明imagemin文档,特别注意的是上面使用了process.env.NODE_ENV当前环境变量,只有在生产环境启用图片压缩,因为压缩过程比较比较耗时,可能会降低开发、调试效率。
数据资源
对于数据类型文件资源,webpack内置支持加载解析.json文件,而其他类型则需要安装配置相应加载器,如.xml文件,需要安装并配置xml-loader。
资源管理的思考
在传统或稍早一点的应用中,我们通常会将所有的图片,字体等资源放在一个基础目录下,如assets/或images,但是对于那些在多项目间重复的插件代码或资源来说,每一次迁移,我们都得在一大堆图片,字体资源里寻找出我们需要迁移的资源,这对代码可重用和其独立性有一定限制,而且与现在提倡的组件化开发模式也不相符。
webpack对于资源的处理方式给组件化开发提供了很大便利,使得我们以组件为单位,可以在某一组件目录下存放所有相关的js,css,图片,字体等资源文件;组件的迁移公用成本很低。不过组件化开发并不是说不需要资源目录了,一些公用的资源依然放在项目的基础目录下。
说明
Ich kann endlich aufatmen. Ich habe eine grundlegende Zusammenfassung der Praxis der Webpack-Verwaltung von CSS, Bildern, Schriftarten und Datenressourcen fertiggestellt. Tatsächlich habe ich das Gefühl, dass es noch viel zu tun gibt Ich muss sicherstellen, dass der Artikel klare Ideen und glatte Sätze enthält und nicht zu lang ist. Das Niveau ist begrenzt und es dauert viel Zeit, ihn zu erfahren. Ich hoffe, dass er für die Leser hilfreich sein kann Die Kapitel werden weiterhin mit Einführungen durchsetzt, um dieser Reihe eine vollständigere und klarere Beschreibung der Verwendung von Webpack zur Entwicklung von SPA-Anwendungen zu geben.
Ich habe das Obige für Sie zusammengestellt und hoffe, dass es Ihnen in Zukunft hilfreich sein wird.
Verwandte Artikel:
Axios zum Hochladen von Dateien in Vue verwenden
So fügen Sie einem Objekt in js ein Array hinzu
So erstellen Sie einen vollständigen Projektprozess mit gulp
Das obige ist der detaillierte Inhalt vonSo verwalten Sie CSS und andere Ressourcen in Webpack und SPA. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!