這次要來做圖片跟 css 的打包。scss 打包說明在文末,概括來說就是多裝幾個 loader。
本篇文章的 demo code 可以在這邊查看:
一樣沿用前面的專案,為了簡單明瞭一點,這次把 router-link 集中放到 header ,移除其他檔案的 router-link。
// header.vue
<template>
<div class="header">
<router-link to="/">HOME</router-link>
<router-link to="/cat2">cat2</router-link>
<router-link to="/cat3">cat3</router-link>
<router-link to="/catAll">catAll</router-link>
<p>header</p>
</div>
</template>
// cat1.vue
<template>
<div style="background: #aabbcc;">
<p>cat1</p>
</div>
</template>
新增 src/assets/images 資料夾,放入圖片,
然後 cat1, cat2, cat3, catAll 各新增一張圖片。
<img src="../assets/images/cat1.png" alt="cat1.png">
順便設定一下 favicon,就是開啟瀏覽器時在頁面名稱旁邊的小 icon,
favicon 可以在 htmlWebpackPlugin 中直接設定:
plugins: [
new VueLoaderPlugin(),
new htmlWebpackPlugin({ // 打包HTML
template: './index.html', // HTML模板路径
favicon: './src/assets/images/favicon.png'
})
]
然後
npm run build
npm run serve
打開頁面會發現,嗯,看不到圖片...
這是因為這邊的路徑我寫的是 cat1.vue 相對於 src 圖片資料夾裡 cat1.png 的路徑,
但現在檔案在讀圖片,
需要的是 index.html 相對於 dist 資料夾中圖片的路徑
改成
<img src="image/cat1.png" alt="cat1.png">
這樣子就可以正常顯示圖片了。
dist 中圖片資料夾的名稱可以在 webpack.config.js 中設定
{
test: /\.(jpe?g|png|gif|woff|woff2|eot|ttf|svg)(\?[a-z0-9=.]+)?$/,
loader: 'file-loader',
options: { name: 'image/[name].[ext]' }
},
路徑會依 options 裡面的配置去打包。
name 圖片原來的名字,預設是 hash
ext 是副檔名
接下來可以很開心的,把 cat2.vue, cat3.vue, catAll.vue 都加上圖片,
然後發現!!怎麼只有 cat1 有圖片???
看看你的 dist 資料夾裡,竟然!!沒有除了 favicon 跟 cat1.png 之外的其他圖片!
也就是說,你的圖片沒有正確的被打包。
這個部分可以用 import 或 require 的方式引入圖片,
例如
<script>
require('../assets/images/cat1.png')
</script>
一樣
npm run build
npm run serve
這樣,dist 資料夾跟頁面就都看得到圖片了。
參考資料
解决vue-cli中webpack无法打包js变量中的图片路径
但是如果我需要這個頁面有 100 張圖片,總不能 require 100次吧?
不用 require 怎麼做呢?
copy-webpack-plugin
安裝個 plugin: copy-webpack-plugin
這個 plugin 可以幫助我們把圖片整個資料夾打包起來。
npm install copy-webpack-plugin --save-dev
// webpack.config.js
module.exports = {
plugins: [
new CopyPlugin([
{ from: './src/assets/images', to: 'image' }
])
],
};
這樣不需要 require,就可以直接把所有指定路徑裡面的圖片打包了。
不過他也會順便幫你打包 favicon,
所以如果你也配置了 htmlWebpackPlugin 的 favicon,
就會 dist 下面有一個 favicon,dist/image 下面也有一個 favicon 了。
參考資料
如果你跟我一樣覺得同時有兩張 favicon 太辣眼睛,可以把 htmlWebpackPlugin 的 favicon 配置取消,
然後直接改 index.html
<head>
<meta charset="UTF-8">
<title>webpackDemo</title>
<link rel="shortcut icon" type="image/png" href="/image/favicon.png"/>
</head>
注意這裡的路徑也是要放打包後 dist 資料夾中的路徑
這樣打包出來就不會有兩個 favicon 啦。
接下來來把 css 拉出來。
新增 src/assets/style/style.css
.header{background: #55ff55;}
.footer{background: #ffaaff;}
.cat1{background: #aabbcc; }
.cat2{background: #bbccdd; }
.cat3{background: #ccddee; }
.catAll{background: #ddeeff;}
各頁面的行內樣式style換成class
ex.
// cat1
<template>
<div class="cat1">
<p>cat1</p>
<img src="image/cat1.png" alt="cat1.png">
</div>
</template>
// index.html 引入 css,這邊的路徑一樣是相對於打包的路徑
<head>
<meta charset="UTF-8">
<title>webpackDemo</title>
<link rel="shortcut icon" type="image/png" href="/image/favicon.png" />
<link rel="stylesheet" href="css/style.css">
</head>
// webpack.config.js 中一樣用 CopyPlugin 做配置
new CopyPlugin([
{ from: './src/assets/images', to: 'image' },
{ from: './src/assets/style', to: 'css' }
])
然後一樣
npm run build
npm run serve
查看打包檔案
現在我們有css跟image資料夾了,樣式也有正常作用,這樣就算成功啦。
2020.02.03 更新。
處理 .scss 檔案
前陣子換工作公司主要用 scss,補充一下 scss 打包方式。
先來安裝幾個 loader。
npm install sass-loader node-sass -D
npm install css-loader mini-css-extract-plugin -D
更新一下設定檔。
// webpack.config.js module.rules
{ test: /\.s[ac]ss$/, loader: [ "style-loader", "css-loader", 'sass-loader' ] },
最後找個檔案來隨便測試一下是否能正常套用樣式,就決定是 header.vue 了。
// header.vue
<style lang="scss" scoped>
.header {
border: solid;
&:hover {
background-color: rgb(164, 162, 255);
}
}
</style>
整理一下頁面,hover 效果正常的話就差不多是沒問題囉。
scss 打包參考 code 也丟 github 了,如果小夥伴們發現好像跟上面的 repository 長得不太一樣,不要懷疑,問就是因為我懶得更新舊的XD
.scss 檔案全域引用
用 scss 最方便的功能之一就是變數了吧,身為一個喜歡用 css 把網站弄得好像很炫砲的前端,都裝那麼多 loaders 了肯定也要來跟風(?)一下。
這裡做個簡單的顏色變數的檔案 _variables.scss,放在 src/assets/style/scss/ 資料夾底下。
// _variables.scss
$mainColor: #ef9595;
更新一下設定檔。
// webpack.config.js module.rules
{ test: /\.s[ac]ss$/, loader: [ "style-loader", "css-loader", 'sass-loader', { loader: 'sass-resources-loader', options: { resources: [ 'src/assets/style/scss/*.scss' ] } } ] },
接著一樣拿上面 header.vue 來測試,就把剛剛寫的 background-color 改成 $mainColor
ps. demo 的分支沒有更新全域引用的部分(專案拿去寫作品集 demo 了,還沒改完,整體進度可以直接點最新 commit 查看)。
background-color: $mainColor;
如果顏色一樣有吃到,就表示引用成功,可以下班囉~
參考資料
Webpack 前端打包工具 - 使用 sass-loader 編譯 Sass/SCSS 預處理器
How to export a global scss variables file to be imported to all scss files in Rails 6 webpacker