從0搭建本身的webpack開發環境(二)

上期回顧: 從0搭建本身的webpack開發環境(一)javascript

loader主要是用於把模塊原內容按照需求轉換成新內容,以便用來加載非 JS 模塊!
經過使用不一樣的loaderWebpack能夠把不一樣的文件都轉成JS文件,好比CSS、ES6/七、JSX等。css

讓咱們來看看這些必需要掌握的loader!html

1.loader的編寫

1.1 loader的使用

  • test:匹配處理文件的擴展名的正則表達式
  • use:loader名稱,就是你要使用模塊的名稱
  • include/exclude:手動指定必須處理的文件夾或屏蔽不須要處理的文件夾
  • options:爲loaders提供額外的設置選項

默認loader的執行順序是從下到上、*從右向左,固然執行順序也能夠手動定義,接下來咱們依次介紹常見的loader,來感覺loader的魅力!java

咱們基於這個基礎配置來繼續編寫:node

const path = require("path");
const dev = require("./webpack.dev");
const prod = require("./webpack.prod");
const merge = require("webpack-merge");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const base = {
  entry:'./src/index.js',
  output: {
    filename: "[name].js",
    path: path.resolve(__dirname, "../dist")
  },
  plugins: [
    new HtmlWebpackPlugin({
        filename: 'index.html',
        template: path.resolve(__dirname, "../public/template.html"),
        hash: true,
        minify: {
            removeAttributeQuotes: true
        }
    }),
    new CleanWebpackPlugin({
        cleanOnceBeforeBuildPatterns: [path.resolve('xxxx/*'),'**/*'],
    }),
  ]
};
module.exports = env => {
  if (env.development) {
    return merge(base, dev);
  } else {
    return merge(base, prod);
  }
};
複製代碼

2.處理CSS文件

2.1 解析css樣式

咱們在js文件中引入css樣式!webpack

import './index.css';
複製代碼

再次執行打包時,會提示css沒法解析git

ERROR in ./src/index.css 1:4
Module parse failed: Unexpected token (1:4)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
複製代碼

這個時候須要安裝loadergithub

npm install style-loader css-loader --save-dev
複製代碼
module: {
  rules: [
    {
       test: /\.css$/,
       use: ["style-loader", "css-loader"]
    }
  ]
}
複製代碼

2.2 抽離樣式文件

默認只在打包時進行樣式抽離web

module.exports = env => {
  let isDev = env.development;
  const base = {/*source...*/}
  if (isDev) {
    return merge(base, dev);
  } else {
    return merge(base, prod);
  }
};

複製代碼

安裝抽離插件正則表達式

npm install mini-css-extract-plugin --save-dev
複製代碼

配置抽離插件

{
    test: /\.css$/,
    use: [
        !isDev && MiniCssExtractPlugin.loader,
        isDev && 'style-loader',
        "css-loader"
    ].filter(Boolean)
}
!isDev && new MiniCssExtractPlugin({
    filename: "css/[name].css"
})
複製代碼

最終文件配置貼一下:

const path = require("path");
const dev = require("./webpack.dev");
const prod = require("./webpack.prod");
const merge = require("webpack-merge");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = env => {
  let isDev = env.development;
  const base = {
    entry: "./src/index.js",
    output: {
      filename: "[name].js",
      path: path.resolve(__dirname, "../dist")
    },
    module: {
      rules: [
        {
          test: /\.css$/,
          use: [
            !isDev && MiniCssExtractPlugin.loader,
            isDev && 'style-loader',
            "css-loader"
          ].filter(Boolean)
        }
      ]
    },
    plugins:[
        !isDev && new MiniCssExtractPlugin({
          filename: "css/[name].css"
        }),
        new HtmlWebpackPlugin({
          filename: "index.html",
          template: path.resolve(__dirname, "../public/template.html"),
          hash: true,
          minify: {
            removeAttributeQuotes: true
          }
        }),
      ].filter(Boolean)
  };
  if (isDev) {
    return merge(base, dev);
  } else {
    return merge(base, prod);
  }
};
複製代碼

2.3 css預處理器

不一樣的css預處理器要安裝不一樣的loader來進行解析

  • sass: sass-loader node-sass
  • less: less-loader less
  • stylus: stylus-loader stylus

使用sass

{
    test:/\.scss$/,
    use:[
        !isDev && MiniCssExtractPlugin.loader,
        isDev && 'style-loader',
        "css-loader",
        "sass-loader"
    ].filter(Boolean)
}
複製代碼

在css文件中可能會使用@import語法引用css文件,被引用的css文件中可能還會導入scss

{
    test: /\.css$/,
    use: [
    !isDev && MiniCssExtractPlugin.loader,
    isDev && 'style-loader',
    {
        loader:"css-loader",
        options:{
            importLoaders:1 // 引入的文件須要調用sass-loader來處理 
        }
    },
    "sass-loader"
    ].filter(Boolean)
},
複製代碼

2.4 處理樣式前綴

使用postcss-loader增長樣式前綴

npm install postcss-loader autoprefixer
複製代碼

在處理css前先增長前綴

{
    test: /\.css$/,
    use: [
    !isDev && MiniCssExtractPlugin.loader,
    isDev && 'style-loader',
    {
        loader:"css-loader",
        options:{
            importLoaders:2 // 引入的文件須要調用sass-loader來處理 
        }
    },
    {
        loader:"postcss-loader",
        options:{
            plugins:[require('autoprefixer')]
        }
    },
    {
        loader:"postcss-loader",
        options:{
            plugins:[require('autoprefixer')]
        }
    },
    "sass-loader"
    ].filter(Boolean)
},
複製代碼

或者也能夠建立postcss的配置文件postcss.config.js

module.exports = {
    plugins:[
        require('autoprefixer')
    ]
}
複製代碼

能夠配置瀏覽器的兼容性範圍 .browserslistrc

cover 99.5%
複製代碼

2.5 css壓縮

在生產環境下咱們須要壓縮css文件,配置minimizer選項,安裝壓縮插件

npm i optimize-css-assets-webpack-plugin terser-webpack-plugin --save-dev
複製代碼

webpack.prod.js文件中配置壓縮

const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
optimization:{
    minimizer:[new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})]
}
複製代碼

2.6 文件指紋

  • Hash:整個項目的hash值
  • chunkhash:根據入口產生hash值
  • contentHash:根據每一個文件的內容產生的hash值

咱們能夠合理的使用hash戳,進行文件的緩存

!isDev && new MiniCssExtractPlugin({
    filename: "css/[name].[contentHash].css"
})
複製代碼

3.處理文件類型

3.1 處理引用的圖片

import logo from './webpack.png';
let img = document.createElement('img');
img.src = logo;
document.body.appendChild(img);
複製代碼

使用file-loader,會將圖片進行打包,並將打包後的路徑返回

{
    test:/\.jpe?g|png|gif/,
    use:{
        loader:'file-loader',
        options:{
            name:`img/[name].[ext]`
        }
    }
}
複製代碼

3.2 處理icon

二進制文件也是使用file-loader來打包

{
    test:/woff|ttf|eot|svg|otf/,
    use:{
        loader:'file-loader'
    }
}
複製代碼

3.3 轉化成base64

使用url-loader將知足條件的圖片轉化成base64,不知足條件的url-loader會自動調用file-loader來進行處理

{
    test:/\.jpe?g|png|gif/,
    use:{
        loader:'url-loader',
        options:{
            limit:100*1024,
            name:`img/[name].[ext]`
        }
    }
}
複製代碼

4.小結

經過對loader的使用,咱們瞭解到loader能夠把其餘類型模塊都處理成JS模塊,以便加載使用。這其實就是webpack中很是重要的混淆依賴中的一部分。 下一篇文章咱們將一塊兒來探討如何解析處理JS模塊,但願你們繼續關注和支持!


相關文章
相關標籤/搜索