webpack4入門和多文件打包嘗試

簡介

按照webpack官網的說法,webpack本質上是javascript應用程序的靜態資源打包器(static module bundler),它能夠將模塊按照依賴和規則打包成符合生產環境部署的前端資源。webpack能夠將按模塊異步加載按需引用,經過loader的轉換還能夠將任何資源看做模塊,好比css、圖片、json、commonjs模塊、amd模塊、es6模塊等。現在webpack的大版本更新到4.x了,讓咱們看下如何使用。javascript

1.安裝使用

新建一個文件夾,依次執行:css

npm init
npm i webpack webpack-cli webpack-server -D
複製代碼

便可開始使用webpack。在文件夾中新建文件夾 srcdist 和文件webpack.config.js,其中 src 爲打包的源目錄用來存放咱們要打包的文件,dist 爲輸出目錄,webpack.config.js 是咱們配置webpack打包相關參數的文件。html

  • 項目目錄

  • webpack.config.js
//webpack.config.js
const path = require('path')

module.exports = {
  // 打包模式,可選development和production
  mode: 'development',
  // 配置入口文件
  entry: './src/index.js',
  // 配置輸出文件
  output: {
    // 輸出路徑
    path: path.resolve(__dirname, './dist'),
    // 輸出文件名稱
    filename: 'build.js'
  },
  // 模塊,可使用各類loader,好比css轉換,圖片壓縮等
  module: {},
  // 插件,用於生成模板和其它功能
  plugins: [],
  // 可配置本地的webpack開發服務功能
  devServer: {}
}
複製代碼

編寫好webpack.config.js以後就使用命令npx webpack開始執行打包了。webpack的打包機制,只能以js文件爲入口,若是你須要打包圖片,css,字體,svg等資源,必須使用es6或commonjs等模塊加載規範在入口文件中引入,不然是無法進行打包構建的。前端

  • module和一些loader的使用

module可使用loader處理引入的模塊,支持的模塊類型有CoffeeScript,TypeScript,ES5/6,sass,less,stylus。模塊的依賴方式有:java

1.ES2015 import 語句
2. CommonJS require() 語句
3. AMD definerequire 語句
4. css/sass/less 文件中的 @import 語句
5. 樣式(url(...))或 HTML 文件(<img src=...>)中的圖片連接(image url)

下面我用一些loader來介紹module的用法,注意使用loader以前須要使用npm安裝對應的loader(npm i xxx-loader -D)webpack

// webpack.config.js
module.exports = {
  mode: '',
  entry: '',
  output: {},
  module: {
    rules: [
      {
        test: /\.css$/, // 匹配css文件模塊
        use: ['style-loader', 'css-loader'] // 使用對應的loader處理
      },
      {
        test: /\.(png|gif|jpe?g|svg)$/, // 匹配圖片文件
        use: [{
          loader: 'file-loader',
          options: {
            name: '[path][name].[ext]?[hash]',
            // 會輸出相似下面這樣的結果
            // path/to/file.png?e43b20c069c4a01867c31e98cbce33c9
          }
        }]
      },
      {
        test: /\.(html)$/, // 用來匹配html文件模塊(html須要經過插件引入?),能夠將html標籤中引入的圖片資源進行打包
        use: [{
          loader: 'html-loader',
          options: {
            attrs: ['<tag>:<attribute>'] // <tag>爲引入圖片的標籤名,<attribute>爲引入圖片的屬性名
          }
        }]
      }
    ]
  },
  plugins: [],
  devServer: {}
}
複製代碼

經過上面例子中幾個loader的使用,大體的介紹了模塊的做用和用法。若是沒有你須要的功能,能夠去webpack官網上去尋找。git

另外還有一個圖片打包url-loader,須要注意它和file-loader的區別。url-loader能夠說是file-loader的進一步封裝,能夠將圖片轉換爲base64格式內聯在代碼中,這樣能夠減小圖片加載的http請求。es6

  • plugins插件的使用

plugins也是webpack的重要功能之一,藉助插件咱們能夠實現loader沒法完成的工做。要使用插件以前,一樣須要使用npm安裝(npm i xxx -D),而且在webpack.config.js中要引用該插件。下面我簡單介紹幾個插件的用法,想要更完整的資料能夠訪問webpack插件github

// webpack.config.js
const path = require('path')
// 使用插件以前須要先加載對應的plugin
const CleanWebpackPlugin = require('clear-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')

module.exports = {
  mode: '',
  entry: {
    a: './src/a.js', // 能夠引入多個入口文件
    b: './src/b.js'
  },
  output: {
    path: path.resolve(__dirname + '/dist/'),
    filename: '[name].[hash:8].js' // 輸出多個結果,文件名帶hash值
  },
  module: {},
  plugins: [
    // 每次構建完成後先清理一遍dist目錄
    new CleanWebpackPlugin(['dist']),
    // 生成html文件到輸入目錄
    new HtmlWebpackPlugin({
      // 能夠以src目錄下的html源文件爲模板
      template: './src/index.html',
      // 在目標目錄下生成目標文件
      filename: './dist/index.html',
      chunks: ['a', 'b'] // 這個參數配合entry能夠將打包的模塊以<script></script>的形式加載到html文件中
    }),
    // 該插件能夠將源目錄中的文件直接複製到目標目錄中
    new CopyWebpackplugin([{
      from: './src/*.css', // 選擇源目錄下的全部css文件
      flatten: true // 選擇拷貝文件仍是包括文件夾,默認是false
    }])
  ],
  devServer: {}
}
複製代碼
  • devServer

devServer能夠在本地搭建一個webpack構建服務環境web

// webpack.config.js
module.exports = {
  mode: '',
  entry: {},
  output: {},
  module: {},
  plugins: [],
  devServer: {
    contentBase: '/dist', // 服務的內容目錄
    port: 4396, // 搭建在本地的服務的端口號
    compress: true, // 服務開啓gzip壓縮
    open: true // 自動打開本地瀏覽器
  }
}
複製代碼

同時將項目目錄下的package.json改寫一下。

// package.json
"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "start": "webpack-dev-server", // 開啓本地的webpack開發服務環境
  "build": "webpack" // 執行打包
}
複製代碼

以後咱們就能夠執行npm run startnpm run webpack開啓服務,執行打包。

2.多文件入口打包

多文件打包的本質就是在入口entry添加多個打包入口,在上面介紹plugins的HtmlWebpackPlugins時就用到了兩個入口。咱們天然而然的想到有多少個入口文件,就在entry裏面添加幾個入口不就行了。這樣雖然能夠實現多文件打包,可是每次咱們新加一個入口都要手動添加,很是麻煩。因此咱們想辦法匹配獲取到源目錄下的全部的入口文件,而後添加到entry中便可。

function getEntry () {
  let globPath = 'src/**/*.html' // 匹配src目錄下的全部文件夾中的html文件
  // (\/|\\\\) 這種寫法是爲了兼容 windows和 mac系統目錄路徑的不一樣寫法
  let pathDir = 'src(\/|\\\\)(.*?)(\/|\\\\)' // 路徑爲src目錄下的全部文件夾
  let files = glob.sync(globPath)
  let dirname, entries = []
  for (let i = 0; i < files.length; i++) {
    dirname = path.dirname(files[i])
    entries.push(dirname.replace(new RegExp('^' + pathDir), '$2').replace('src/', ''))
  }
  return entries
}

function addEntry () {
  let entryObj = {}
  getEntry().forEach(item => {
    entryObj[item] = resolve(__dirname, 'src', item, 'index.js')
  })
  return entryObj
}
複製代碼

經過上面兩個方法咱們就能獲取到src目錄下的全部入口文件。下面咱們看webpack.config.js如何修改

// ...
{
  // entry: resolve(__dirname, "src/home/index.js")
  // 改成
  entry: addEntry()
  //...
}
// ...

getEntry().forEach(pathname => {
  let conf = {
    filename: pathname.replace('src/', '') + '.html',
    template: path.join(__dirname, 'src', pathname, 'index.html'),
    chunks: Array.call([], pathname)
  }
  webpackconfig.plugins.push(new HtmlWebpackPlugin(conf))
})
複製代碼

這樣咱們就可以實現自動的匹配全部入口文件和要生成的html模板文件,同時在HtmlWebpackPlugin插件使用時,也自動添加了多個模板入口,在目標目錄下生成多個html文件。

上面只是大體介紹了多入口的思路,具體代碼能夠看我實現的一個demo多頁面打包

參考文章

webpack文檔

webpack4.x入門配置

webpack多入口文件頁面打包配置

webpack前端多頁項目工程

原文連接:tech.gtxlab.com/webpack4.ht…


做者簡介: 宮晨光,人和將來大數據前端工程師。

相關文章
相關標籤/搜索