加載 CSS
爲了從 JavaScript 模塊中 import
一個 CSS 文件,你須要在 module
配置中 安裝並添加 style-loader 和 css-loader:css
npm install --save-dev style-loader css-loader
webpack.config.jshtml
const path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, + module: { + rules: [ + { + test: /\.css$/, + use: [ + 'style-loader', + 'css-loader' + ] + } + ] + } };
webpack 根據正則表達式,來肯定應該查找哪些文件,並將其提供給指定的 loader。在這種狀況下,以
.css
結尾的所有文件,都將被提供給style-loader
和css-loader
。node
這使你能夠在依賴於此樣式的文件中 import './style.css'
。如今,當該模塊運行時,含有 CSS 字符串的 <style>
標籤,將被插入到 html 文件的 <head>
中。webpack
咱們嘗試一下,經過在項目中添加一個新的 style.css
文件,並將其導入到咱們的 index.js
中:git
projectgithub
webpack-demo |- package.json |- webpack.config.js |- /dist |- bundle.js |- index.html |- /src + |- style.css |- index.js |- /node_modules
src/style.cssweb
.hello { color: red; }
src/index.jsajax
import _ from 'lodash'; + import './style.css'; function component() { var element = document.createElement('div'); // lodash 是由當前 script 腳本 import 導入進來的 element.innerHTML = _.join(['Hello', 'webpack'], ' '); + element.classList.add('hello'); return element; } document.body.appendChild(component());
如今運行構建命令:正則表達式
npm run build Hash: 9a3abfc96300ef87880f Version: webpack 2.6.1 Time: 834ms Asset Size Chunks Chunk Names bundle.js 560 kB 0 [emitted] [big] main [0] ./~/lodash/lodash.js 540 kB {0} [built] [1] ./src/style.css 1 kB {0} [built] [2] ./~/css-loader!./src/style.css 191 bytes {0} [built] [3] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built] [4] ./~/style-loader/lib/addStyles.js 8.7 kB {0} [built] [5] ./~/style-loader/lib/urls.js 3.01 kB {0} [built] [6] (webpack)/buildin/global.js 509 bytes {0} [built] [7] (webpack)/buildin/module.js 517 bytes {0} [built] [8] ./src/index.js 351 bytes {0} [built]
再次在瀏覽器中打開 index.html
,你應該看到 Hello webpack
如今的樣式是紅色。要查看 webpack 作了什麼,請檢查頁面(不要查看頁面源代碼,由於它不會顯示結果),並查看頁面的 head 標籤。它應該包含咱們在 index.js
中導入的 style 塊元素。npm
請注意,在多數狀況下,你也能夠進行 CSS 分離,以便在生產環境中節省加載時間。最重要的是,現有的 loader 能夠支持任何你能夠想到的 CSS 處理器風格 - postcss, sass 和 less 等。
加載圖片
假想,如今咱們正在下載 CSS,可是咱們的背景和圖標這些圖片,要如何處理呢?使用 file-loader,咱們能夠輕鬆地將這些內容混合到 CSS 中:
npm install --save-dev file-loader
webpack.config.js
const path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }, + { + test: /\.(png|svg|jpg|gif)$/, + use: [ + 'file-loader' + ] + } ] } };
如今,當你 import MyImage from './my-image.png'
,該圖像將被處理並添加到 output
目錄,_而且_ MyImage
變量將包含該圖像在處理後的最終 url。當使用 css-loader 時,如上所示,你的 CSS 中的 url('./my-image.png')
會使用相似的過程去處理。loader 會識別這是一個本地文件,並將 './my-image.png'
路徑,替換爲輸出
目錄中圖像的最終路徑。html-loader 以相同的方式處理 <img src="./my-image.png" />
。
咱們向項目添加一個圖像,而後看它是如何工做的,你可使用任何你喜歡的圖像:
project
webpack-demo |- package.json |- webpack.config.js |- /dist |- bundle.js |- index.html |- /src + |- icon.png |- style.css |- index.js |- /node_modules
src/index.js
import _ from 'lodash'; import './style.css'; + import Icon from './icon.png'; function component() { var element = document.createElement('div'); // Lodash,如今由此腳本導入 element.innerHTML = _.join(['Hello', 'webpack'], ' '); element.classList.add('hello'); + // 將圖像添加到咱們現有的 div。 + var myIcon = new Image(); + myIcon.src = Icon; + + element.appendChild(myIcon); return element; } document.body.appendChild(component());
src/style.css
.hello { color: red; + background: url('./icon.png'); }
讓咱們從新構建,並再次打開 index.html 文件:
npm run build Hash: 854865050ea3c1c7f237 Version: webpack 2.6.1 Time: 895ms Asset Size Chunks Chunk Names 5c999da72346a995e7e2718865d019c8.png 11.3 kB [emitted] bundle.js 561 kB 0 [emitted] [big] main [0] ./src/icon.png 82 bytes {0} [built] [1] ./~/lodash/lodash.js 540 kB {0} [built] [2] ./src/style.css 1 kB {0} [built] [3] ./~/css-loader!./src/style.css 242 bytes {0} [built] [4] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built] [5] ./~/style-loader/lib/addStyles.js 8.7 kB {0} [built] [6] ./~/style-loader/lib/urls.js 3.01 kB {0} [built] [7] (webpack)/buildin/global.js 509 bytes {0} [built] [8] (webpack)/buildin/module.js 517 bytes {0} [built] [9] ./src/index.js 503 bytes {0} [built]
若是一切順利,和 Hello webpack
文本旁邊的 img
元素同樣,如今看到的圖標是重複的背景圖片。若是你檢查此元素,你將看到實際的文件名已更改成像 5c999da72346a995e7e2718865d019c8.png
同樣。這意味着 webpack 在 src
文件夾中找到咱們的文件,併成功處理過它!
合乎邏輯下一步是,壓縮和優化你的圖像。查看 image-webpack-loader 和 url-loader,以瞭解更多關於若是加強加載處理圖片功能。
加載字體
那麼,像字體這樣的其餘資源如何處理呢?file-loader 和 url-loader 能夠接收並加載任何文件,而後將其輸出到構建目錄。這就是說,咱們能夠將它們用於任何類型的文件,包括字體。讓咱們更新 webpack.config.js
來處理字體文件:
webpack.config.js
const path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }, { test: /\.(png|svg|jpg|gif)$/, use: [ 'file-loader' ] }, + { + test: /\.(woff|woff2|eot|ttf|otf)$/, + use: [ + 'file-loader' + ] + } ] } };
在項目中添加一些字體文件:
project
webpack-demo |- package.json |- webpack.config.js |- /dist |- bundle.js |- index.html |- /src + |- my-font.woff + |- my-font.woff2 |- icon.png |- style.css |- index.js |- /node_modules
經過配置好 loader 並將字體文件放在合適的地方,你能夠經過一個 @font-face
聲明引入。本地的 url(...)
指令會被 webpack 獲取處理,就像它處理圖片資源同樣:
src/style.css
+ @font-face { + font-family: 'MyFont'; + src: url('./my-font.woff2') format('woff2'), + url('./my-font.woff') format('woff'); + font-weight: 600; + font-style: normal; + } .hello { color: red; + font-family: 'MyFont'; background: url('./icon.png'); }
如今讓咱們從新構建來看看 webpack 是否處理了咱們的字體:
npm run build Hash: b4aef94169088c79ed1c Version: webpack 2.6.1 Time: 775ms Asset Size Chunks Chunk Names 5c999da72346a995e7e2718865d019c8.png 11.3 kB [emitted] 11aebbbd407bcc3ab1e914ca0238d24d.woff 221 kB [emitted] bundle.js 561 kB 0 [emitted] [big] main [0] ./src/icon.png 82 bytes {0} [built] [1] ./~/lodash/lodash.js 540 kB {0} [built] [2] ./src/style.css 1 kB {0} [built] [3] ./~/css-loader!./src/style.css 420 bytes {0} [built] [4] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built] [5] ./src/MyFont.woff 83 bytes {0} [built] [6] ./~/style-loader/lib/addStyles.js 8.7 kB {0} [built] [7] ./~/style-loader/lib/urls.js 3.01 kB {0} [built] [8] (webpack)/buildin/global.js 509 bytes {0} [built] [9] (webpack)/buildin/module.js 517 bytes {0} [built] [10] ./src/index.js 503 bytes {0} [built]
從新打開 index.html
看看咱們的 Hello webpack
文本顯示是否換上了新的字體。若是一切順利,你應該能看到變化。
加載數據
此外,能夠加載的有用資源還有數據,如 JSON 文件,CSV、TSV 和 XML。相似於 NodeJS,JSON 支持其實是內置的,也就是說 import Data from './data.json'
默認將正常運行。要導入 CSV、TSV 和 XML,你可使用 csv-loader 和 xml-loader。讓咱們處理這三類文件:
npm install --save-dev csv-loader xml-loader
webpack.config.js
const path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }, { test: /\.(png|svg|jpg|gif)$/, use: [ 'file-loader' ] }, { test: /\.(woff|woff2|eot|ttf|otf)$/, use: [ 'file-loader' ] }, + { + test: /\.(csv|tsv)$/, + use: [ + 'csv-loader' + ] + }, + { + test: /\.xml$/, + use: [ + 'xml-loader' + ] + } ] } };
給你的項目添加一些數據文件:
project
webpack-demo |- package.json |- webpack.config.js |- /dist |- bundle.js |- index.html |- /src + |- data.xml |- my-font.woff |- my-font.woff2 |- icon.png |- style.css |- index.js |- /node_modules
src/data.xml
<?xml version="1.0" encoding="UTF-8"?> <note> <to>Mary</to> <from>John</from> <heading>Reminder</heading> <body>Call Cindy on Tuesday</body> </note>
如今,你能夠 import
這四種類型的數據(JSON, CSV, TSV, XML)中的任何一種,所導入的 Data
變量將包含可直接使用的已解析 JSON:
src/index.js
import _ from 'lodash'; import './style.css'; import Icon from './icon.png'; + import Data from './data.xml'; function component() { var element = document.createElement('div'); // Lodash, now imported by this script element.innerHTML = _.join(['Hello', 'webpack'], ' '); element.classList.add('hello'); // Add the image to our existing div. var myIcon = new Image(); myIcon.src = Icon; element.appendChild(myIcon); + console.log(Data); return element; } document.body.appendChild(component());
當你打開 index.html
並查看開發者工具中的控制檯,你應該可以看到你導入的數據被打印在了上面!
在使用 d3 等工具來實現某些數據可視化時,預加載數據會很是有用。咱們能夠不用再發送 ajax 請求,而後於運行時解析數據,而是在構建過程當中將其提早載入並打包到模塊中,以便瀏覽器加載模塊後,能夠當即從模塊中解析數據。
全局資源
上述全部內容中最出色之處是,以這種方式加載資源,你能夠以更直觀的方式將模塊和資源組合在一塊兒。無需依賴於含有所有資源的 /assets
目錄,而是將資源與代碼組合在一塊兒。例如,相似這樣的結構會很是有用:
- |- /assets + |– /components + | |– /my-component + | | |– index.jsx + | | |– index.css + | | |– icon.svg + | | |– img.png
這種配置方式會使你的代碼更具有可移植性,由於現有的統一放置的方式會形成全部資源緊密耦合在一塊兒。假如你想在另外一個項目中使用 /my-component
,只需將其複製或移動到 /components
目錄下。只要你已經安裝了任何擴展依賴(external dependencies),而且你已經在配置中定義過相同的 loader,那麼項目應該可以良好運行。
可是,假如你沒法使用新的開發方式,只能被固定於舊有開發方式,或者你有一些在多個組件(視圖、模板、模塊等)之間共享的資源。你仍然能夠將這些資源存儲在公共目錄(base directory)中,甚至配合使用 alias 來使它們更方便 import 導入
。
回退處理
對於接下來的指南,咱們無需使用本指南中全部用到的資源,所以咱們會進行一些清理工做,以便爲下一部分指南中的管理輸出章節作好準備:
project
webpack-demo |- package.json |- webpack.config.js |- /dist |- bundle.js |- index.html |- /src - |- data.xml - |- my-font.woff - |- my-font.woff2 - |- icon.png - |- style.css |- index.js |- /node_modules
webpack.config.js
const path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, - module: { - rules: [ - { - test: /\.css$/, - use: [ - 'style-loader', - 'css-loader' - ] - }, - { - test: /\.(png|svg|jpg|gif)$/, - use: [ - 'file-loader' - ] - }, - { - test: /\.(woff|woff2|eot|ttf|otf)$/, - use: [ - 'file-loader' - ] - }, - { - test: /\.(csv|tsv)$/, - use: [ - 'csv-loader' - ] - }, - { - test: /\.xml$/, - use: [ - 'xml-loader' - ] - } - ] - } };
src/index.js
import _ from 'lodash'; - import './style.css'; - import Icon from './icon.png'; - import Data from './data.xml'; - function component() { var element = document.createElement('div'); - - // Lodash,如今經過 script 標籤導入 element.innerHTML = _.join(['Hello', 'webpack'], ' '); - element.classList.add('hello'); - - // 將圖像添加到咱們已有的 div 中。 - var myIcon = new Image(); - myIcon.src = Icon; - - element.appendChild(myIcon); - - console.log(Data); return element; } document.body.appendChild(component());