webpack4.0入門配置文件

wepback風頭正火 ,可是公司一直在用gulp,正好遇上年末活動,藉此機會第一次嘗試了webpack,說實話webpack真的很強大,內容一層一層遞進。css

這幾天跟着官網跑了一遍,而後寫了本身的配置文件,由於活動內容很少,不少強大的功能沒有用上,可是相信對於入門來講足夠了。html

下面來總結並附上源碼前端

當 webpack 處理應用程序時,它會遞歸地構建一個依賴關係圖,其中包含應用程序須要的每一個模塊,而後將全部這些模塊打包成一個或多個 bundle。

webpack支持的模塊語法有哪些?

ES6,CommonJs,Amdnode

webpack和gulp的區別?

Webpack能夠經過衆多loader和plugin完成許多gulp上的功能,但Webpack本質在於模塊打包,而gulp的本質在於執行任務;使用webpack-stream包能夠實現gulp和webpack的搭配使用jquery

核心概念webpack

1.入口:指定使用哪一個模塊來做爲構建內部依賴圖的開始,隨後打包成bundleweb

2.輸出:定義輸出生產的bundle的位置及文件名;npm

3.loader:讓webpack能夠處理非js模塊;loader 能夠將全部類型的文件轉換爲webpack 可以處理的有效模塊。json

4. 插件:執行的任務範圍包括從打包優化和壓縮,一直到從新定義環境中的變量,目的在於完成一些loader沒法完成的任務。gulp

經常使用配置項

1.mode: ‘development’|| ‘production’ || ‘none’

2.entry:  array || obj

3.output: {

  path: path.resolve(__dirname, "dist"), // 輸出文件的目標路徑

  filename:’bundle.js’,// 打包後的文件名

  publicPath: ‘static’// 輸出解析文件目錄,url相對於html

}

4.module: {

  rules: [

    {

              test: /\.js$/, // 指定使用此loader的文件

              use: ‘babel-loader’,

              options: { },

              include: /src/, // 匹配項

      exclude: /node_modules/ // 非匹配項

    }

    ]

  }

 5.plugins: […instance]

 6.devServer: {

  host: ‘localhost’,

  port: ‘8080’,

  contentBase: Boolean|| string || array, // 服務器從哪裏獲取內容

  hot:boolean, // 是否開啓webpack模塊熱替換

  open: Boolean, // 是否自動打開瀏覽器

  proxy: { path: targetUrl}, // 代理

    …others

  }

7.resolve: {

  alias: {

    test: url

    },

  extensions: [.js, .json]

 }

 8.devtool: string || false

   可選值:

  cheap-eval-source-map

  eval-source-map

  cheap-source-map

  source-map

  cheap-module-eval-source-map

  …others

經常使用loaderplugin

loader

Css-loader:解析css中資源路徑;

Sass-loader:sass轉碼爲css

Postcss-loader:使webpack能夠用postcss處理css

Px2rem-loader: px轉換爲rem

Style-loader:將css以style標籤的形式插入到dom中

Babel-loader:轉碼js以提升兼容性

url-loader:圖片轉base64

webpack imagemin-webpack-plugin 壓縮圖片

file-loader:將文件輸出到輸出目錄並返回文件路徑

html-loader:處理html中資源路徑                        

eslint-loader:使js支持eslint

plugin

html-webpack-plugin:根據模板導出html文件,並注入bundle

DinePlugin: 建立編譯時能夠進行配置的全局變量。

HashedModuleIdsPlugin: 根據模塊的相對路徑生成一個四位數的hash做爲模塊id

extract-text-webpack-plugin:分離css

mini-css-extract-plugin:分離css

uglifyjs-webpack-plugin:壓縮js

optimize-css-assets-webpack-plugin:壓縮css

clean-webpack-plugin: 清空某個目錄

cli經常使用命令

--config 使用指定的配置文件

 --env.key=value 指定環境變量

--mode=production 指定模式

--progress 打印編譯進度的百分比

--display-error-details 展現錯誤細節

--define 定義環境變量

-w 觀察文件變化,變化後從新執行構建流程

--hot 開啓模塊熱替換

--json > stats.json 將編譯結果的各類信息輸出爲json文件

--profile 捕獲編譯時每一個步驟的時間信息

配置文件編寫

前端常見需求:

  1)       Js壓縮

  2)       Css壓縮

  3)       Css提取

  4)       小圖片轉base64

  5)       Px轉rem

  6)       Css前綴添加

  7)       Sass轉碼

  8)       Babel轉碼

  9)       文件名加hash

  10)       文件編碼格式轉換(常見utf-8與gbk互轉)

  11)       代碼分離

  12)       Eslint

  13)       模塊熱替換

  14)       配置編譯過程的全局變量

  15)       打包後的代碼注入html中

1.    經常使用模塊變量

  __dirname:當前文件夾路徑

 2.    經常使用佔位符

    [hash]:模塊標識符的hash(後拼接:‘:n’可指定長度)

  [chunkhash]: chunk內容的hash(後拼接:‘:n’可指定長度)

  [name]:模塊名稱

  [id]: 模塊標識符

3. 配置文件使用commonjs編寫的,配置類型有下面幾種:

    1) 導出一個配置對象

  2) 導出一個函數

  3) 導出一個promise

代碼分離

 該功能能夠把代碼分離到不一樣的 bundle 中,而後能夠按需加載或並行加載這些文件。代碼分離能夠用於獲取更小的 bundle,以及控制資源加載優先級,若是使用合理,會極大影響加載時間。

代碼分離的方式:

  1.手動配置多個入口文件

  2.使用webpack自帶的splitChunks功能

  3.使用import()動態導入

下面附上本身的web.config.js

//生成html文件 npm i -D html-webpack-plugin
const HtmlWebpackPlugin = require('html-webpack-plugin');
//每次打包前清理目錄文件 npm i -D clean-webpack-plugin
const CleanWebpackPlugin = require('clean-webpack-plugin');
//js壓縮 npm i -D uglifyjs-webpack-plugin
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
//單獨打包css,webpack3是利用extract-text-webpack-plugin插件提取單獨打包css文件
//webpack4得使用mini-css-extract-plugin npm i -D mini-css-extract-plugin
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
//壓縮css npm i -D optimize-css-assets-webpack-plugin
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
//用於打包後的文件轉碼 npm i webpack-encoding-plugin
const EncodingPlugin = require("webpack-encoding-plugin");
//提取公共模塊 請參考https://segmentfault.com/a/1190000012828879
//引入glob正則匹配多頁面 npm i -D glob
var glob = require('glob');
//安裝webpack npm i -D webpack@<version>(版本號)
//webpack4後將webpack-cli分別出來要本身安裝 npm in -D webpack-cli
const webpack = require('webpack');
//處理文件路徑的工具
const path = require('path');
//設置變量判斷是開發環境仍是生產環境 npm i -D cross-env
const devMode = process.env.NODE_ENV !== 'production';
//獲取全部路口js,生成一個路徑對象.
var getEntry = function () {
var entry = {};
  //首先咱們先讀取咱們的開發目錄
  glob.sync('./source/**/*.js').forEach(function (name) {
    var n = name.slice(name.lastIndexOf('source/') + 7, name.length - 3);
    n = n.slice(0, n.lastIndexOf('/'));
    //接着對路徑字符串進行了一些裁剪成想要的路徑
    entry[n] = name;
  });
  console.log(entry);
  /**
    *    entry = {
    *               'crowd/index' : './source/main/index/index.js',
    *               'index/index' : './source/content/index/index.js'
    *           }
  *
  **/
  //最後返回entry 給 webpack的entry
  return entry;
};
module.exports = {
  entry: getEntry(), //入口文件
  output: { //文件輸出位置
  path: path.resolve(__dirname, 'dist'), //配置輸出路徑
    filename: "js/[name].bundle.js", //文件輸出形式
    chunkFilename: "js/[name].chunk.js",
    publicPath: '/'//虛擬目錄,自動指向path編譯目錄
},
//tips:chunkFilename網上以爲靠譜的解釋
//chunkname是未被列在entry中,卻又須要被打包出來的文件命名配置。什麼場景須要呢?在按需加載(異步)模塊的時候,
//這樣的文件是沒有被列在entry中的,如使用CommonJS的方式異步加載模塊:
// require.ensure(["modules/tips.jsx"], function(require) {
// var a = require("modules/tips.jsx");
// // ...
// }, 'tips');

//tips:通常來講,引入第三方庫有一下三種狀況:
// 經過CDN引入;
// 經過npm 安裝並引入;
// 第三方js文件就在本地
resolve: {//一些配置項,如第三方的js文件就在本地,怎麼經過webpack引入
  alias: {
    $: path.resolve(__dirname, './dist/jquery.js'),
    jQuery: path.resolve(__dirname, './dist/jquery.js'),
  }
},
plugins: [ //插件
 
  require("autoprefixer"),//引入自動補全前綴,直接引入autoprefixer-loader並無生效,
  //安裝postcss-loader並引入autoprefixer時生效,並建立postcss.config.js文件
  new webpack.HotModuleReplacementPlugin(),//啓動模塊熱替換
  new webpack.NamedModulesPlugin(), //用於啓動HMR時能夠顯示模塊的相對路徑
  new UglifyJsPlugin({}),//js壓縮
  new MiniCssExtractPlugin({//css分離
    filename: devMode ? 'css/[name].css' : 'css/[name].[hash:5].css',
    chunkFilename: devMode ? 'css/[id].css' : 'css/[id].[hash:5].css',
  }),
  new OptimizeCSSAssetsPlugin({}),//css壓縮
  //多頁應用時配置多個html時,那麼就須要實例化該插件屢次
  new HtmlWebpackPlugin({
    template: 'src/html/index.html',
    excludeChunks: ['list', 'detail']//配置不容許注入的chunk
  }),
  new HtmlWebpackPlugin({
    filename: 'list.html',
    template: 'src/html/list.html',
    chunks: ['common', 'list']//容許插入到模板中的一些chunk,不配置此項默認會將entry中全部的chunk注入到模板中
  }),
  new HtmlWebpackPlugin({
    filename: 'detail.html',
    template: 'src/html/detail.html',
    chunks: ['common', 'detail']
  }),
  //用來項目的轉碼
  new EncodingPlugin({
    encoding: 'GB2312'
  }),
  //清除dist文件夾
  new CleanWebpackPlugin(['dist'])
],
//模塊
module: {
  rules: [
  {
    test: /\.js$/,
    use: [
    {
      loader: 'babel-loader',//cnpm i -D babel-loader @babel/core @babel/preset-env webpack
      options: {//npm i -S babel-polyfill 實現瀏覽器對不支持API的兼容(兼容舊環境、填補)
      presets: ['@babel/preset-env']
    }
  }
],
  exclude: /node_modules/
},
{
  test: /\.(sa|sc|c)ss$/,
  use: [//npm i -D style-loader css-loader
    devMode ? 'style-loader' : MiniCssExtractPlugin.loader,//由於MiniCssExtractPlugin不支持熱替換,因此當是生產環境時不啓用這個插件
    'css-loader',
    'postcss-loader',//npm i -D postcss-loader
    // {網上還有這種寫法
    // loader: 'postcss-loader',
    // options: {
      // plugins: () => [
      // require('autoprefixer')
    // ],
  // }
// },
  'sass-loader',//使用sass-loader要使用node-loader,npm i -D sass-loader node-sass
  {
  loader: 'px2rem-loader',//配合flexible實現移動端下的適配 npm i px2rem-loader
  // options here
    options: {
      remUni: 75,
      remPrecision: 8
    }
  }
  ]
},
{
  test: /\.(jpg|png|gif|jpeg)$/,
  use: [ {//npm i -D url-loader
    loader: 'url-loader',// 在文件大小(單位 byte)低於指定的限制時,能夠返回一個 DataURL。
    options: {
      limit: 10000,//設置字節限制
      name: 'img/[name]_[hash:5].[ext]'
    }
  } ]
 }
]
},
//配置開發服務功能 npm i -D webpack-dev-server
devServer: {
  contentBase: path.resolve(__dirname, 'dist'),
  historyApiFallback: true,
  hot: true,
  port: 9000,
  publicPath:'/',
  }
};
相關文章
相關標籤/搜索