webpack配置及踩過的那些坑

最近學習了一波webpack打包部署,作為一名前端授艰,不會一個打包的工具可真的是丟人啊辨嗽。不過,用webpack又要接觸到了配置文件淮腾,這個當初當我放棄寫后端的東西糟需,不過以后還是要全面發(fā)展的。好了谷朝,話不多說洲押,這篇文章用的是webpack4.x版本的,下面將細數(shù)當初才過的坑圆凰。

1.基礎準備

創(chuàng)建一個文件夾webpackDemo杈帐,我們使用命令行進入這個文件夾,運行 npm init 命令专钉,初始化這個文件夾挑童,初始化過程中出現(xiàn)的詢問的一些配置,一路回車就好了跃须。初始化好了之后站叼,我們會發(fā)現(xiàn)文件夾里面已經(jīng)多了package.json文件。

npm install webpack --save-dev webpack-cli --save-dev

安裝必要的 webpack 和 webpack-cli菇民,安裝成功之后的package.json文件如下

在根目錄下創(chuàng)建如下的目錄結構

test.js文件里面編寫如下代碼尽楔,一萬年經(jīng)典的Hello World

document.write("Hello World");

index.html里面編寫代碼

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>Webpack初探</title>
</head>

<body>
    <script src="./dist/js/bundle.js"></script>
</body>

</html>

這邊引用一個bundle.js文件,bundle.js文件使我們打包之后生成的文件第练,接下來使用webpack的打包命令進行打包

webpack src/apps/test.js -o dist/js/bundle.js

wepack的基礎打包命令 webpack {entryFile} -o {aimFile} 執(zhí)行完之后會發(fā)現(xiàn)我們的目錄里已經(jīng)生成了 bundle.js 文件阔馋,我們運行 index.html 文件,可以看到親切的Hello World了娇掏。
打包過程中垦缅,出現(xiàn)的輸出如下

這邊會顯示webpack打包一共花了501ms,打包后的 bundle.js 體積是957bytes驹碍,因為我們的代碼比較簡單壁涎,所以打包生成的文件還是很小的。

2.webpack.config.js配置文件

在根目錄下創(chuàng)建文件 webpack.config.js 這是weback運行所要依據(jù)的配置志秃。大致分為入口配置怔球,出口配置,loader配置浮还,plugins配置

2.1 entry和output###

entry配置的是入口文件竟坛,告訴webpack從哪個文件開始解析,分為單入口和多入口钧舌。有了入口担汤,就要配置出口,配置打包生成的文件位置和文件名稱洼冻。在webpack.config.js里面編寫如下代碼

const path = require('path');
module.exports = {
    entry: path.resolve(__dirname, 'src/apps/test.js'),
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: "js/bundle.js",
    }
}

首先這邊引用的pathnode.js的一個模塊崭歧,是用來解析路徑用的,path.resolve指的是當前文件的所在路徑撞牢,那么這邊我們entry配置的就是/src/apps/test.js率碾,這是單入口的配置形式。
下面對出口進行配置屋彪,output是一個對象所宰,基礎的兩個屬性,一個是輸出文件的路徑畜挥,另一個是輸出文件的名稱仔粥。
package.json里面編寫如下代碼:

這邊配置一下webpack的打包命令,之后通過npm run start進行打包蟹但,就不需要輸一大串的命令了躯泰。打包一下我們可以看一下控制臺的輸出

發(fā)現(xiàn)有一個warning,這是因為我們還沒有配置我們的mode矮湘,我們修改webpack.config.js文件

const path = require('path');
module.exports = {
    mode: 'development',
    devtool: 'source-map',
    entry: path.resolve(__dirname, 'src/apps/test.js'),
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: "js/bundle.js",
    }
}

在打包一下會發(fā)現(xiàn)這邊的warning已經(jīng)沒有了斟冕。

2.2 devtool配置

上面的配置文件我們是加了一個devtool的配置,這是因為webpack打包后的這個文件缅阳,我們可以看一下磕蛇,已經(jīng)不是我們所熟知的代碼了,這樣不方便于我們的調試十办,所以webpack為了解決這個問題秀撇,有一個devtool的配置。這邊給一個別人博客的傳送門webpack之devtool詳解向族,webpack官方解釋

2.3 loader配置

loader配置是webpack中的重點呵燕,因為webpack默認是只能處理html文件,如果要處理比如react應用中的jsx文件那么就需要配置一下loader件相,或者js再扭、css等文件氧苍,都需要配置一下loader。這邊已react應用為例泛范。由于目前瀏覽器的兼容性問題让虐,所以我們需要大量的插件和loader來轉換我們寫的高級js語法,就有了各種es6轉es5罢荡,es7啥的赡突。具體的還得好好研究。首先安裝react相關的插件

 npm install react --save react-dom --save

安裝解析react的相關插件和解析es6語法的相關插件区赵。

npm install babel-loader -save-dev babel-core --save-dev babel-preset-env --save-dev babel-preset-react --save-dev

babel-core
把 js 代碼分析成 ast (抽象語法樹, 是源代碼的抽象語法結構的樹狀表現(xiàn)形式)惭缰,方便各個插件分析語法進行相應的處理。有些新語法在低版本 js 中是不存在的笼才,如箭頭函數(shù)漱受,rest 參數(shù),函數(shù)默認值等患整,這種語言層面的不兼容只能通過將代碼轉為 ast拜效,再通過語法轉換器分析其語法后轉為低版本 js。

babel-preset-*
babel-preset-* 代表了一系列的轉碼插件
有了 babel-plugin 系列各谚,可以按需配置自己想要的特性紧憾,若是想搭個 es6 環(huán)境,一個個地配置各個插件昌渤,我猜你會瘋掉赴穗。babel-preset 系列就可以滿足我們的需求,babel-preset 系列打包了一組插件膀息,類似于餐廳的套餐般眉。如 babel-preset-es2015 打包了 es6 的特性,babel-preset-stage-0 打包處于 strawman 階段的語法

下面看具體的配置潜支,配置文件如下甸赃,這邊首先我們要將package.json文件里面的babel-loader的版本更換成7.1.5然后重新安裝一下模塊,不然下面會因為babel-loader的版本問題出現(xiàn)打包失敗的問題冗酿。

// webpack.config.js
const path = require('path');
module.exports = {

    mode: 'development',

    devtool: 'source-map',

    entry: path.resolve(__dirname, 'src/apps/console.jsx'),

    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: "js/bundle.js",
    },

    module: {
        rules: [{
            test: /(\.js)|(\.jsx)$/,
            exclude: /node_modules/,
            use: {
                loader: 'babel-loader',
                options: {
                    presets: ['env', 'react']
                }
            }
        }]
    }
}

test 指明要對哪一種后綴的文件進行解析埠对,使用正則進行驗證
exclude 規(guī)定一些文件夾或文件不參與解析
use.loader 配置使用的loader名稱
use.option 配置loader的其他選項,這邊的presets是告訴webpack解析react語法和es6語法裁替。

// console.jsx
import React from 'react';
import ReactDOM from 'react-dom';

const mountNode = document.getElementById("root");

class App extends React.Component {
    constructor(props) {
        super(props)
    }
    render() {
        return (
            <div>
                Hello China!
            </div>
        );
    }
}

ReactDOM.render(<App />, mountNode);

執(zhí)行npm run start项玛,然后運行我們的index.html文件可以看到Hello China!弱判。

2.4 plugin配置

插件賦予了webpack更多的功能襟沮,比如說 js和css分離打包。比如說happyPack的多線程打包,比如說每次打包前自動清空dist目錄开伏。
以js膀跌、css分離打包為例,這是使用的extract-text-webpack-plugin插件硅则,
首先安裝一下淹父,注意這邊安裝的是extract-text-webpack-plugin@next而不是extract-text-webpack-plugin

 npm install --save-dev extract-text-webpack-plugin@next
 npm install style-loader --save-dev css-loader --save-dev
// webpack.config.js
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {

    mode: 'development',

    devtool: 'source-map',

    entry: path.resolve(__dirname, 'src/apps/console.jsx'),

    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: "js/bundle.js",
    },

    module: {
        rules: [{
            test: /(\.js)|(\.jsx)$/,
            exclude: /node_modules/,
            use: {
                loader: 'babel-loader',
                options: {
                    presets: ['env', 'react']
                }
            }
        }, {
            test: /\.css$/i,
            use: ExtractTextPlugin.extract({
                fallback: 'style-loader',
                use: ['css-loader']
            })
        }]
    },

    plugins: [
        new ExtractTextPlugin({
            filename: 'style/css/[name].css',
            allChunks: true 
        })
    ]
}

2.5 其他配置###

stats配置

在進行webpack打包的時候會出現(xiàn)很多的輸出,但是有的輸出是我們不需要看見的輸出怎虫,這就可以采用stats進行配置

// 對webpack輸出信息的配置,可以減少一些不必要的輸出
stats: {
    children: false
}

resolve.extensions 解決引入模塊不需要加后綴

// extensions 自動解決擴展困介,配置這個在引用模塊時不用加后綴
// modules 配置解析模塊的搜索目錄
// path.resolve 返回參數(shù)的絕對路徑  path.join 拼接路徑 然后返回絕對路徑
resolve: {
        modules: [path.resolve(__dirname, 'node_modules'), path.join(__dirname, 'src')],
        extensions: ['.wasm', '.mjs', '.js', '.json', '.jsx']
    },

optimization配置 抽離公共模塊

optimization: {
    minimize: false,
    splitChunks: {
        chunks: 'all',
        name: 'common'
    }
},

last.一些解釋及踩過的那些坑

last.1 npm install 的時候 --save-dev 和--save的區(qū)別

首先這邊的 --save 是將我們install的包寫進package.json文件里面大审,后面的-dev才是要描述的重點,-dev是寫進我們的devDependencies里面座哩,如果不加這個那么是寫進dependencies里面的徒扶,在生產(chǎn)環(huán)境下,是不會安裝devDependencies里面的包的根穷。這邊找了一個別人的博客姜骡,寫的比我這個更全面一點。對--save-dev和--save的區(qū)別詳解

last.2 webpack基礎命令打包的時候報ERROR in multi ./src/apps/test.js dist/js/bundle.js

Module not found: Error: Can't resolve 'dist/js/bundle.js' in 'F:\WebDemo\webpackDemo'

這是因為webpack的版本問題屿良,在webpack4.x版本之前的打包命令是

webpack {entryFile} {aimFile}

但是在webpack4.x開始基礎打包命令就變成了

webpack {entryFile} -o {aimFile}

last.3出現(xiàn)Error: Cannot find module '@babel/core'###

這是因為babel-loader版本的問題圈澈,如果之前我們安裝babel-loader的時候是采用npm install babel-loader這樣寫的話是默認安裝最新版本的babel-loader最新的是8.x的,我們回退到7.1.5版本就可以避免這個報錯了尘惧。

last.4 webpack-dev-server問題

1.webpack-dev-server 不會讀取webpack.config.js配置的output也不會將生產(chǎn)的文件添加進項目目錄里
2.webpack-dev-server 生成的文件和你dist里面的文件不是同一個文件康栈。dist里面的是output里面決定
的webpack-dev-server打包生成的文件位置取決于contentBase配置

last.5 的 package.json里面的打包命令###

--colors 輸出結果帶有顏色
--profile 輸出性能數(shù)據(jù)看見每一步的耗時
--proress 輸出當前的編譯進度
--display-error-details 輸出詳細的錯誤信息

lats.6 使用extractTextPlugin時報 Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead###

這是因為安裝extract-text-webpack-plugin的時候安裝命令問題,實際上我們需要安裝的是

"extract-text-webpack-plugin": "^4.0.0-beta.0",

解決辦法喷橙,刪除之前安裝的extract插件啥么,更換安裝命令為

npm install --save-dev extract-text-webpack-plugin@next

last.7 入口文件配置[name].js 但是打包出來的文件總是main.js并不會根據(jù)入口名稱決定出口名稱###

這邊的main.js main是取決你的主入口的,就是在執(zhí)行npm init的時候那一堆默認的主入口贰逾。之所以沒有按照入口文件來改變出口文件的名稱悬荣,是因為入口文件采用的單入口的形式,也就是如下寫法

entry: path.resolve(__dirname, 'src/apps/console.jsx')

使用單入口的形式疙剑,那么

output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'js/[name].js'
    },

打包生成的文件只會有一個main.js 并不會生成console.js
解決辦法是將單入口的寫法換成多入口的形式氯迂,也就是下面這種寫法

entry: {
        console: path.resolve(__dirname, 'src/apps/console')
    },

這樣打包出來的文件就是console.js

last.7 bundle.js和vendor.js的引入順序問題###

vendor.js一定是最先引用的,因為bundle.js要依賴于vendor.js生存核芽。

last.8 名詞解釋

webpack.config.dev.js 開發(fā)環(huán)境下的webpack配置文件
webpack.config.prod.js 生產(chǎn)環(huán)境下的配置文件
vendor.js 這是打包我們引入的第三方包的囚戚。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市轧简,隨后出現(xiàn)的幾起案子驰坊,更是在濱河造成了極大的恐慌,老刑警劉巖哮独,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拳芙,死亡現(xiàn)場離奇詭異察藐,居然都是意外死亡,警方通過查閱死者的電腦和手機舟扎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門分飞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人睹限,你說我怎么就攤上這事譬猫。” “怎么了羡疗?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵染服,是天一觀的道長。 經(jīng)常有香客問我叨恨,道長柳刮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任痒钝,我火速辦了婚禮秉颗,結果婚禮上,老公的妹妹穿的比我還像新娘送矩。我一直安慰自己蚕甥,他們只是感情好,可當我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布益愈。 她就那樣靜靜地躺著梢灭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蒸其。 梳的紋絲不亂的頭發(fā)上敏释,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天,我揣著相機與錄音摸袁,去河邊找鬼钥顽。 笑死,一個胖子當著我的面吹牛靠汁,可吹牛的內容都是我干的蜂大。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蝶怔,長吁一口氣:“原來是場噩夢啊……” “哼奶浦!你這毒婦竟也來了?” 一聲冷哼從身側響起踢星,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤澳叉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體成洗,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡五督,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了瓶殃。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片充包。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖遥椿,靈堂內的尸體忽然破棺而出基矮,到底是詐尸還是另有隱情,我是刑警寧澤修壕,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布愈捅,位于F島的核電站,受9級特大地震影響慈鸠,放射性物質發(fā)生泄漏。R本人自食惡果不足惜灌具,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一青团、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧咖楣,春花似錦督笆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至珠十,卻和暖如春料扰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背焙蹭。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工晒杈, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人孔厉。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓拯钻,卻偏偏與公主長得像,于是被迫代替她去往敵國和親撰豺。 傳聞我的和親對象是個殘疾皇子粪般,可洞房花燭夜當晚...
    茶點故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內容