webpack4 學習 --- webpack和webpack-dev-server

  直入主題吧,建個文件夾webpack-tut並進入,打開cmd命令窗口,執行npm init -y 命令,建立package.json 文件,轉化爲了node 項目,這樣好管理依賴和版本什麼的。此時能夠學習webpack了。首先要安裝webpack,不過這裏要注意,webpack4 把webpack 命令單獨抽了出來,造成了一個單獨的包webpack-cli ,咱們安裝webpack的同時要把它安裝上css

npm install webpack webpack-cli --save-dev

  webpack命令,就是咱們在命令窗口中寫的命令,咱們在cmd 命令窗口中,輸入webpack,  就會把打包,webpack 就是一個命令。爲何要單獨造成一個包呢?由於webpack-cli 還提供了兩個其它的功能,init 和 migrate命令,使咱們快速建立webpack 配置和提供升級遷移。不過這兩個基本不用,瞭解一下就能夠了。咱們只要記住安裝webpack的同時安裝上webpack-cli就能夠了。html

  webpack 是模塊打包工具,那就建幾個文件讓它打包,在webpack-tut 文件夾中新建一個src 文件夾,存放咱們的源文件,再在src 文件夾中新建index.js 文件和component.js 文件,component.js 文件前端

export default (text = 'hello world') => {
  const element = document.createElement('div');
  element.innerHTML = text;

  return element;
}

index.js 文件node

import component from './component';
document.body.appendChild(component());

  怎麼打包呢?在webpack4 下,直接執行webpack 命令。在package.json的scripts的字段中,寫上 「build」: 「webpack」,  執行npm run build 命令,生成了dist 目錄,表示打包成功了,但也發現了一個WARNINGwebpack

  Webpack4 提供了一個mode 配置項 ,它有兩個選擇: production 和 development, 就是生產模式和開發模式,不一樣模式,配置確定不同。mode 能夠在命令行進行配置,   build 命令改爲 webpack --mode production  或 webpack --mode development,就配置成功了。ios

  以上就是webpack4 提供的零配置。簡單總結一下,當執行webpack命令,而又沒有配置文件時,webpack會尋找默認的入口文件。默認的入口文件就是項目根目錄下的src目錄下的index.js文件,這也是新建src 目錄和把js文件命名爲index.js 的緣由。打包後文件,它也定義了默認的輸出路徑,打包後的文件放到dist 目錄中, 文件名爲main.js 文件, 同時,它還會根據你指定的mode 進行打包優化。web

  對於小型的項目,零配置沒有問題,但對於大型的web 項目,它不光有js, 還有css, image 等,零配置就無能爲力,仍是要退回寫webpack的配置文件。在webpack-tut中新建webpack.config.js 文件(配置文件的默認名稱),配置文件和之前相同,都是entry, output, module, plugins選項。 零配置的時候,webpack 給咱們提供了entry 和output, 若是以爲ok的話,可使用,那配置文件中,只寫module 和plugins 就能夠,若是以爲不ok 的話,能夠寫entry 和output, 把它覆蓋掉,這都沒有問題, mode 的配置也是如此,能夠在命令行中指定,也能夠在配置文件中書寫,如今用配置文件的方式,把零配置實現一下正則表達式

const path = require('path');

module.exports = {
    mode: 'development',
    entry: path.join(__dirname, 'src/index.js'),
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'main.js'
    }
}

  npm run build 也打包成功了,最後驗證一下,在根目錄下建一個html 文件,script 引入 dist/main.js, 沒有問題。但這時你也會發現一個問題,改動js文件後,都要執行npm run build 命令,同時要手動刷新瀏覽器才能看效果,很是麻煩,不利於開發,怎麼辦? 使用webpack-dev-server, 自動打包,自動刷新npm

  webpack-dev-server 是 webpack自帶的一個小型服務器,它會檢測每一個文件的變更,每當有文件改動時,它就會從新打包,而後瀏覽器會自動刷新頁面,這樣就能夠時時看到代碼的變更,大大開發了開發效率。這也是所謂的liveload 或hotload(熱更新)。但這裏要注意,webpack-dev-server 打包後文件是放到內存中的,而不像npm run build 把文件打包到硬盤上,默認狀況下,webpack會把打包生成的文件生成到根目錄下,就至關於在根目下多了打包後的文件,能夠經過開發者工具的source 面板來查看一下。json

     首先 npm install webpack-dev-server --save-dev 安裝它,而後在scripts中,"dev": "webpack-dev-server", 

 

  npm run dev 啓動服務器,但當咱們更改代碼,頁面刷新但內容並無進行改變,這是由於index.html 裏面訪問的js 文件是 dist 文件夾中的main.js, 而不是webpack 打包後生成的文件。把dist 文件夾刪除,頁面直接報錯了,找不到main.js 文件,上面已經說了,webpack-dev-server 會把文件打包到項目根目錄下,因此index.html 文件中應該引入當前文件夾下面的main.js。

<body>
  <script src="./main.js"></script>
</body>

  npm run dev 和npm run build 命令下,index.html 引入的js 文件路不一致,可使用html-webpack-plugin 插件解決。npm install html-webpack-plugin --save-dev 安裝,

插件的使用方式也簡單,配置文件中有一個plugins 屬性,它是一個數組,每個用到的插件都是數組中的一項。具體到每個插件呢?插件都會暴露出構造函數,經過new 調用,就可使用,若是插件還有配置項,它就給構造函數傳遞參數,只傳一個對象做爲參數

const path = require('path');
const htmlWebpackPlugin = require('html-webpack-plugin'); // 引入插件

module.exports = {
    mode: 'development',
    entry: path.join(__dirname, 'src/index.js'),
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'main.js'
    },
    plugins: [
        new htmlWebpackPlugin({  // 插件的使用: new 調用構造函數,配置項就是構造函數的參數(對象形式的參數)
            template: 'index.html'
        })
    ]
}

  這時npm run dev 和npm run build都沒有問題。這時我想對webpack-dev-server 進行配置,好比把端口改成9000, 配置文件提供了一個devServer 配置項,這個配置項和entry, output,module並列。devServer的配置是很龐大人,這裏只是學幾個簡單實用的配置

module.exports = {
    devServer: {
        port: 9000,  // 設置端口號
        stats: 'errors-only', // 只有產生錯誤的時候,才顯示錯誤信息,日誌的輸出等級是error.
        overlay: true // 當有編譯錯誤的時候,在瀏覽器頁面上顯示。
    },
    plugins: [
        new htmlWebpackPlugin()
    ]
}

  重啓服務器,這時看到項目啓動在9000端口下。

  這時你也應該發現了一個問題,就是當咱們修改配置文件的時候,咱們都要從新啓動服務器,這有點麻煩,是否是能夠監聽配置文件的變化,自動重啓服務器,這就要用到nodemon, nodemon 就是監聽文件變化,重啓服務器的。先安裝nodemon, npm install nodemon --save-dev, 而後把 dev 命令改成下面

"dev": "nodemon --watch webpack.config.js --exec \"webpack-dev-server \""

  命令的意思是 監聽webpack.config.js 的變化,而後執行(exec) webpack-dev-server 命令,注意\'' 雙引號的轉義。

  webpack-dev-server  還有兩個配置項須要注意一下:

  contentBase: webpack-dev-server 會把全部的靜態文件(css, js, img 等)進行打包,放到服務器根目錄下,供咱們訪問。但咱們能夠訪問服務器中的任何資源,一旦這些資源不是由webpack-dev-server 打包生成的,咱們就要指定這些非打包生成的靜態資源,好比index.html 文件,的位置,也就是contentbase,不然就會顯示404. 若是不使用webpack-html-plugin, webpack 是不會打包生成index.html的, 那咱們就要手動建立index.html, 這時index.html 文件,就是非webpack-dev-server 打包生成的資源,咱們就要指定它的位置。由於咱們在瀏覽器中輸入localhost:8080, 咱們是向webpack-dev-server 請求index.html 資源,webpack-dev-server 並無生成這個文件,因此就會報錯,若是告訴webpack-dev-server, index.html 在什麼地方,它就會去找,就不會報錯了。這就是contentbase的做用,webpack-dev-server 會向contentbase 指定的目錄去找它沒有打包生成的文件,你可能說,咱們手動建立index.html時,也沒有指定contnetbase, 整個項目也沒有問題,這是由於contentbase的默認值是項目根目錄,而咱們建立的index.html 恰巧也在項目根目錄下,因此沒有問題。若是咱們在項目根目錄下新建一個文件夾叫public, 而後把index.html 放到裏面,你再運行webapck-dev-serve , 它就會報錯,這時就要指定contentbase, 它的取值就很清楚了,index.html(非webpack-dev-server 打包的資源)所在的位置, 絕對路徑和相對路徑均可以, 相對路徑"build", 它是相對於項目根目錄的, 絕對路徑,path.join(__dirname, ‘public’)

  proxy: 代理,作過先後端聯調,都知道代理的做用。當咱們在本地開發的時候,訪問的服務器是localhost. 可是後端的代碼卻在同事的電腦上,咱們要訪問同事的服務,就要設置代理了,要否則訪問的永遠都是本地的服務localhost,一個接口都沒有。咱們在請求的接口面前加一個標識,如axios.post(‘/api/login’), /api 就是標識,而後咱們再在proxy 配置項裏面給這個標識配置一個代理到的真實路徑,如 ‘/api’ : ‘http://102.03.34.58/api’, 那麼當咱們調用接口的時候,實際上變成了http://102.03.34.58/api/login, 代理配置中的真實路徑,就是會替換到請求中的標示

module.exports = {
    devServer: {
        contentBase:'build', 
        proxy: {
            '/api': 'http://102.03.34.58/api'
        },
        port: 9000,  // 設置端口號
        stats: 'errors-only', // 只有產生錯誤的時候,才顯示錯誤信息,日誌的輸出等級是error.
        overlay: true // 當有編譯錯誤的時候,在瀏覽器頁面上顯示。
    },
    plugins: [
        new htmlWebpackPlugin()
    ]
}    

  但有時候,多是多個同事進行開發,接口沒有那麼規範,可能有的以api 開始,有的沒有api, 根本就沒有統一的標識,以上這種配置方式確定不行, '/api' 標識還能夠是一個對象

proxy: {
    '/api': {
       target: 'http://102.03.34.58',
       pathRewrite: { '^/api': '' }
    }
}

  這裏要注意target 是請求的服務器地址,後面沒有api, 使用這種方式配置之後,代理會在前端請求中的/api前面加上target, 至關於仍是請求了 http://102.03.34.58/api/login,因此這裏增長了pathRewrite 路徑重寫,全部以/api 開頭的路徑都轉化爲 空,因此最後真實的請求路徑中 http://102.03.34.58/login. pathRewrite 中的屬性是正則表達式,^以什麼開始, 值 呢?就是匹配到的路徑重寫成會什麼。

  proxy 中的屬性'/api', 是前端發送請求時,請求接口中的url要加的參數,當真正發送請求時,webpack 服務中配置的代理碰到api 就會攔截,而後把它變成咱們配置的真實的路徑

相關文章
相關標籤/搜索