Coding - 碼農筆記 / pug / webpack / 常用筆記

如何設定 webpack 筆記

筆記如何透過 webpack , 編譯 sass(scss) 和 pug …. 及如何打包 css 引入 js 中

webpack 常用安裝

  1. 初始化 npm init
  2. 安裝 webpack npm install --save-dev webpack webpack-cli
  3. 安裝 cross-env 設定環境變數 npm install --save-dev cross-env
  4. 新增 css-loader npm install --save-dev css-loader style-loader
  5. 獨立拆分出 css npm install --save-dev extract-text-webpack-plugin@next
  6. 安裝 postcss 和 autoprefixer npm install --save-dev postcss-loader autoprefixer
  7. 使用 file-loader 來搬移 html 的檔案 npm install --save-dev file-loader
  8. 安裝 sass npm install --save-dev node-sass sass-loader
  9. 安裝 webpack-dev-server npm install --save-dev webpack-dev-server
  10. 設定 webpack 的 resolve 在引入模塊時省略路徑
  11. 安裝 url-loader來將指定尺寸以下的圖片轉成base64 npm install --save-dev url-loader
  12. 安裝 image-webpack-loader 壓縮圖片 npm install --save-dev image-webpack-loader
  13. 使用 pug npm install --save-dev html-loader pug-html-loader html-webpack-plugin
  14. include 和 exclude 檔案的打包與排除
  15. 安裝 babel-loader 來轉譯高版本的js npm install --save-dev babel-loader @babel/core @babel/preset-env
  16. 安裝 CopyWebPackPlugin 來搬移不需編譯的檔案 npm install --save-dev copy-webpack-plugin
  17. 安裝 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轉換

© 2024 胡同筆記 | WordPress Theme: Cosimo by CrestaProject.