筆記如何透過 webpack , 編譯 sass(scss) 和 pug …. 及如何打包 css 引入 js 中
webpack 常用安裝
- 初始化
npm init
- 安裝 webpack
npm install --save-dev webpack webpack-cli
- 安裝 cross-env 設定環境變數
npm install --save-dev cross-env
- 新增 css-loader
npm install --save-dev css-loader style-loader
- 獨立拆分出 css
npm install --save-dev extract-text-webpack-plugin@next
- 安裝 postcss 和 autoprefixer
npm install --save-dev postcss-loader autoprefixer
- 使用 file-loader 來搬移 html 的檔案
npm install --save-dev file-loader
- 安裝 sass
npm install --save-dev node-sass sass-loader
- 安裝 webpack-dev-server
npm install --save-dev webpack-dev-server
- 設定 webpack 的 resolve 在引入模塊時省略路徑
- 安裝 url-loader來將指定尺寸以下的圖片轉成base64
npm install --save-dev url-loader
- 安裝 image-webpack-loader 壓縮圖片
npm install --save-dev image-webpack-loader
- 使用 pug
npm install --save-dev html-loader pug-html-loader html-webpack-plugin
- include 和 exclude 檔案的打包與排除
- 安裝 babel-loader 來轉譯高版本的js
npm install --save-dev babel-loader @babel/core @babel/preset-env
- 安裝 CopyWebPackPlugin 來搬移不需編譯的檔案
npm install --save-dev copy-webpack-plugin
- 安裝 babel/polyfill 來解決在舊版 ie 不支援的js語法
npm install --save @babel/polyfill
完整的 webpack.config.js 的設定內容
var path = require('path') var ExtractTextPlugin = require('extract-text-webpack-plugin') var extractCSS = new ExtractTextPlugin('css/[name].css') var CopyWebpackPlugin = require('copy-webpack-plugin') var HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { context: path.resolve(__dirname, 'src'), entry: { index: 'index.js', about: 'about.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: './js/[name].js?[hash:8]' }, resolve: { modules: [ path.resolve('src'), path.resolve('src/js'), path.resolve('src/sass'), path.resolve('src/images'), path.resolve('src/assets'), path.resolve('src/pug'), path.resolve('node_modules') ], extensions: ['.js'] }, devServer: { compress: true, port: 3000, stats: { assets: true, cached: false, chunkModules: false, chunkOrigins: false, chunks: false, colors: true, hash: false, modules: false, reasons: false, versions: false, warnings: false } }, module: { rules: [ { test: /\.(pug)$/, use: [ 'html-loader', { loader: 'pug-html-loader', options: { pretty: true } } ], include: path.resolve('src/pug'), exclude: path.resolve('./node_modules') }, { test: /\.css$/, use: extractCSS.extract(['css-loader', 'postcss-loader']), include: path.resolve('src/css'), exclude: path.resolve('./node_modules') }, { test: /\.(sass|scss)$/, use: extractCSS.extract([ 'css-loader', 'postcss-loader', 'sass-loader' ]), include: path.resolve('src/sass'), exclude: path.resolve('./node_modules') }, { test: /\.js$/, use: 'babel-loader', include: path.resolve('.') }, { test: /\.(jpe?g|png|gif)$/, use: [ { loader: 'url-loader', options: { limit: 8192, name: '[path][name].[ext]?[hash:8]' } }, { loader: 'image-webpack-loader', options: { mozjpeg: { progressive: true, quality: 65 }, optipng: { enabled: false }, pngquant: { quality: '65-90', speed: 4 }, gifsicle: { interlaced: false } } } ], include: path.resolve('src/images'), exclude: path.resolve('./node_modules') } ] }, plugins: [ extractCSS, new CopyWebpackPlugin([{ from: 'assets', to: 'assets' }]), new HtmlWebpackPlugin({ title: 'pug轉換', filename: 'index.html', template: 'pug/index.pug', chunks: ['index'] }), new HtmlWebpackPlugin({ title: 'pug轉換', filename: 'about.html', template: 'pug/about.pug', chunks: ['about'] }) ] }
path.resolve() 可以將相對路徑或路徑片段解析成絕對路徑
__dirname nodejs 裡特殊的變數,指當前執行文件的完整目錄位置,搭配 content 組出絕對路徑
完整的 package.json 的設定內容
{ "name": "webpack-basic", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "watch": "NODE_ENV=development webpack --mode development --watch", "start": "NODE_ENV=development webpack --mode development", "deploy": "NODE_ENV=production webpack --mode production", "dev": "NODE_ENV=development webpack-dev-server --mode development --open --host 電腦的ip位址" }, "author": "", "license": "ISC", "devDependencies": { "@babel/core": "^7.5.5", "@babel/preset-env": "^7.5.5", "autoprefixer": "^9.6.1", "babel-loader": "^8.0.6", "copy-webpack-plugin": "^5.0.4", "cross-env": "^5.2.0", "css-loader": "^3.2.0", "extract-text-webpack-plugin": "^4.0.0-beta.0", "file-loader": "^4.2.0", "html-loader": "^0.5.5", "html-webpack-plugin": "^3.2.0", "image-webpack-loader": "^5.0.0", "node-sass": "^4.12.0", "postcss-loader": "^3.0.0", "pug-html-loader": "^1.1.5", "sass-loader": "^7.3.1", "style-loader": "^1.0.0", "url-loader": "^2.1.0", "webpack": "^4.39.2", "webpack-cli": "^3.3.7", "webpack-dev-server": "^3.8.0" }, "dependencies": { "@babel/polyfill": "^7.4.4" } }
安裝 webpack , webpack-cli
npm install --save-dev webpack webpack-cli
新增 webpack.config.js
安裝 cross-env 設定環境變數
npm install --save-dev cross-env
// package.json 新增以下設定 "scripts": { "start": "NODE_ENV=development webpack --mode development", "deploy": "NODE_ENV=production webpack --mode production", "watch": "NODE_ENV=development webpack --mode development --watch", },
新增多重進入點
// webpack.config.js entry: { index: './index.js', about: './about.js' }, output: { path: path.resolve(__dirname, './dist'), filename: '[name].js' }
新增 css loader
npm install --save-dev css-loader style-loader
新增 css-loader 規則
// webpack.config.js module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] }, ] }
loader 的執行順序都是由後往前執行,所以會先執行 postcss-loader,再執行 css-loader
在 index.js 中引入 css, css會被編入 index.js中, html中不需再引入 css
import '../css/index.css'
獨立拆分出 css
npm install --save-dev extract-text-webpack-plugin@next
var ExtractTextPlugin = require('extract-text-webpack-plugin') var extractCSS = new ExtractTextPlugin('css/[name].css') use: extractCSS.extract(['css-loader'])
如 css 不併入 js,要把 ‘style-loader’拿掉
安裝 postcss 和 autoprefixer
npm install --save-dev postcss-loader autoprefixer
新增 postcss.config.js
// postcss.config.js module.exports = { plugins: [ require('autoprefixer')({ grid: true, overrideBrowserslist: [ '> 1%', 'last 5 versions', 'Firefox >= 45', 'ios >= 8', 'ie >= 10' ] }) ] }
新增使用 postcss-loader
// webpack.config.js use: extractCSS.extract(['css-loader', 'postcss-loader'])
使用 file-loader 來搬移 html 的檔案
npm install --save-dev file-loader
// webpack.config.js 新增 file-loader 規則 { test: /\.html$/, use: [ { loader: 'file-loader', options: { name: '[path][name].[ext]' } } ] }
透過 index.js 中要引入 index.html, 即會將 html 檔案一併打包到 dist 裡
import '../index.html'
安裝 sass
npm install --save-dev node-sass sass-loader
// webpack.config.js { test: /\.(sass|scss)$/, use: [ 'style-loader', 'css-loader', 'postcss-loader', 'sass-loader' ] },
在 index.js 裡 import index.sass 即可將 sass編譯後的 css 併入 index.js
如要將 sass 編譯到獨立的 css 資料夾,則需將規則修改如下
use: extractCSS.extract(['css-loader', 'postcss-loader', 'sass-loader']) # 原本在 index.js 裡的 sass 也不用 import 了
安裝 webpack-dev-server
npm install --save-dev webpack-dev-server
// webpack.config.js devServer: { compress: true, port: 3000, stats: { assets: true, cached: false, chunkModules: false, chunkOrigins: false, chunks: false, colors: true, hash: false, modules: false, reasons: false, versions: false, warnings: false } },
package.json 中的 scripts 新增 dev
"dev": "NODE_ENV=development webpack-dev-server --mode development --open"
執行 npm run dev
時不會產生 dist 資料夾,sass 由 index.js 引入
執行 npm run deploy
才會編譯可上線的檔案(包含 html/css)
"dev": "NODE_ENV=development webpack-dev-server --mode development --open --host 10.0.1.8"
加上 –host x.x.x.x 即可手機同步看到編譯的結果
安裝 CopyWebPackPlugin 來搬移不需編譯的檔案
npm install --save-dev copy-webpack-plugin
// webpack.config.js var CopyWebpackPlugin = require('copy-webpack-plugin') # 在 plugins 的地方新增規則 plugins: [ extractCSS, new CopyWebpackPlugin([ { from: 'assets', to: 'assets'} ]) ]
新增 assets 資料夾放置不需編輯的資料
安裝 url-loader來將指定尺寸以下的圖片轉成base64
npm install --save-dev url-loader
需搭配 style-loader,將css注入到js使用
// webpack.config.js { test: /\.(jpe?g|png|gif)$/, use: [ { loader: 'url-loader', options: { # limit: 小於 8192 大小的圖片會轉換成 base64的格式,注入 js limit: 8192, name: '[path][name].[ext]?[hash:8]' } } ] } # sass loader 需改成如下: { test: /\.(sass|scss)$/, use: [ 'style-loader', 'css-loader', 'postcss-loader', 'sass-loader' ] }, # resolve 裡加入 images 的規則 resolve: { modules: [ path.resolve('./src/images'), ], extensions: ['.js'] },
安裝 image-webpack-loader 來將圖片壓縮
npm install --save-dev image-webpack-loader
跟 url-loader 共用設定,加入以下設定
// webpack.config.js { loader: 'image-webpack-loader', options: { mozjpeg: { progressive: true, quality: 65 }, optipng: { enabled: false }, pngquant: { quality: '65-90', speed: 4 }, gifsicle: { interlaced: false } } }
設定 webpack 的 resolve 在引入模塊時省略路徑
// webpack.config.js resolve: { modules: [ path.resolve('./src'), path.resolve('./src/js'), path.resolve('./src/js/Object'), path.resolve('./src/sass'), path.resolve('./src/images'), path.resolve('./src/assets'), path.resolve('./node_modules') ], extensions: ['.js'] },
extensions: [’.js’] 表示在 import js 時可以省略 .js 的副檔名
resolve省略檔名路徑僅限開發時使用,output裡的路徑不能省略
resolve省略檔名路徑僅限在 js 裡使用,在其他(如css)不能使用,如要使用則需加 ~,如 background: url(’~cat.jpg’)
使用 pug
npm install --save-dev html-loader pug-html-loader html-webpack-plugin
// webpack.config.js # 先引入 plugin var HtmlWebpackPlugin = require('html-webpack-plugin') # 加入規則 { test: /\.(pug)$/, use: ['html-loader', 'pug-html-loader'] }, # plugins 裡新增 new HtmlWebpackPlugin({ title: 'pug轉換', filename: 'about.html', template: 'pug/about.pug', chunks: ['about'] }) ]
使用 html webpack plugin 產生html,在 index.js 裡就不用再 import index.js, 也不需要 html 的 file-loader
檔案的打包與排除
設置include 跟exclude 可以提升一定程度的打包效率
include 表示哪些目錄中的文件需要進行loader轉換
exclude 表示哪些目錄中的文件不需要進行loader轉換