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


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

npm install webpack webpack-cli --save-dev

  webpack命令,就是我們在命令窗口中寫的命令,我們在cmd 命令窗口中,輸入webpack,  就會把打包,webpack 就是一個命令。為什么要單獨形成一個包呢?因為webpack-cli 還提供了兩個其它的功能,init 和 migrate命令,使我們快速創建webpack 配置和提供升級遷移。不過這兩個基本不用,了解一下就可以了。我們只要記住安裝webpack的同時安裝上webpack-cli就可以了。

  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 文件

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

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

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

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

  對於小型的項目,零配置沒有問題,但對於大型的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, 自動打包,自動刷新

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

     首先 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 就會攔截,然后把它變成我們配置的真實的路徑

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM