使用webpack2.0 搭建前端項目

  • 什么是webpack:

webpack可以看做是模塊打包機:它做的事情是循衰,分析你的項目結(jié)構(gòu)烫葬,找到JavaScript模塊以及其它的一些瀏覽器不能直接運行的拓展語言(Scss,TypeScript等)局义,并將其打包為合適的格式以供瀏覽器使用

  • 初始化項目

npm init
npm install webpack --save-dev

  • 安裝loader类茂,stylus以及postCss

npm install style-loader css-loader stylus-loader stylus --save-dev
npm install --save-dev postcss-loader autoprefixer

  • 目錄結(jié)構(gòu)大致如下

1080406-20170220122357960-412737218.png

](http://upload-images.jianshu.io/upload_images/6380152-7223197e999ecdd3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

  • 添加webpack.config.js 配置如下

// 該配置基于webpack2.0 詳情查看 https://webpack.js.org/guides/migrating/
const path = require('path'); // 導(dǎo)入路徑包
module.exports = {
entry: './src/main.js', //入口文件
output: {
path: path.resolve(__dirname, 'build'), // 指定打包之后的文件夾
     // publicPath: '/assets/', // 指定資源文件引用的目錄,也就是說用/assests/這個路徑指代path矾兜,開啟這個配置的話损趋,index.html中應(yīng)該要引用的路徑全部改為'/assets/...'
// filename: 'bundle.js' // 指定打包為一個文件 bundle.js
filename: '[name].js' // 可以打包為多個文件
},
// 使用loader模塊
module: {
/* 在webpack2.0版本已經(jīng)將 module.loaders 改為 module.rules 為了兼容性考慮以前的聲明方法任然可用,
      同時鏈?zhǔn)絣oader(用!連接)只適用于module.loader椅寺,
      同時-loader不可省略 */
rules: [{
test: /.css$/,
use: [
'style-loader', {
loader: 'css-loader',
options: {
// modules: true // 設(shè)置css模塊化,詳情參考https://github.com/css-modules/css-modules
}
}, {
loader: 'postcss-loader',

                // 在這里進行配置浑槽,也可以在postcss.config.js中進行配置,詳情參考https://github.com/postcss/postcss-loader
                options: {
                    plugins: function() {
                        return [
                            require('autoprefixer')
                        ];
                    }
                }
            }
        ]
    }, {
        test: /\.styl(us)?$/,
        use: [
            'style-loader', 'css-loader', {
                loader: "postcss-loader",
                options: {
                    plugins: function() {
                        return [
                            require('autoprefixer')
                        ];
                    }
                }
            }, 'stylus-loader'
        ]
    }]
}

}

在index.html中引入'/build/main.js'返帕。main.js 代碼如下

require('./common/css/style.css'); require('./common/css/stylus.styl');

  • 通過webpack-dev-server實現(xiàn)頁面的自動刷新桐玻。

首先安裝webpack-dev-server

npm install --save-dev webpack-dev-server

然后修改package.json配置文件中:

"scripts": {
"start": "webpack-dev-server",
"build": "webpack"
}

使用npm start 啟動服務(wù)。npm的 start是一個特殊的腳本名稱荆萤,它的特殊性表現(xiàn)在镊靴,在命令行中使用npm start就可以執(zhí)行相關(guān)命令,如果對應(yīng)的此腳本名稱不是start链韭,想要在命令行中運行時偏竟,需要這樣用npm run {script name},所以打包命令修改為npm run build敞峭。

這里如果使用webpack-dev-server 命令來啟動就必須全局安裝 devServer:
npm install webpack-dev-server -g

在webpack的配置文件中可以對devServer進行配置

// 配置devServer各種參數(shù)
devServer: {
contentBase: "./", // 本地服務(wù)器所加載的頁面所在的目錄
historyApiFallback: true, // 不跳轉(zhuǎn)
inline: true // 實時刷新
}

此時可以監(jiān)聽入口文件的改變踊谋,實時刷新頁面,然而非入口文件的改變則不會被監(jiān)聽到旋讹,需要手動進行刷新殖蚕。并且目標(biāo)文件不包括index.html。這里使用html-webpack-plugin插件骗村。

npm install html-webpack-plugin --save-dev

修改webpack配置文件嫌褪,添加以下配置:

const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
....,
plugins: [
new HtmlWebpackPlugin({
template: './index.html' // 模版文件
})
]
}

這里記錄一下遇到的坑:首先,devServer其實讀取的是打包之后的文件胚股,但是這些文件是存儲在內(nèi)存當(dāng)中(并不會顯示在build下)。然后由于使用HtmlWebpackPlugin這個插件裙秋,它可以自動幫你將打包的js插入模版html文件中琅拌,因此我們要將原文件(就是作為模版的index.html文件)中插入的main.js這行代碼去掉缨伊。然后如果開啟了publicPath這個選項,HtmlWebpackPlugin會插入publicPth選項的路徑('/assets/main.js')进宝,devServer的index.html此時是無法讀取到該目錄下的文件刻坊。但是奇怪的是devServer此時直接沒有插入該scripts。党晋。不知道為啥谭胚。。但是為了部署的問題未玻,cdn啥的灾而,對開發(fā)環(huán)境和生產(chǎn)環(huán)境應(yīng)該開啟不同的publicPath,也就是說開發(fā)和生產(chǎn)應(yīng)該使用兩個不同的配置文件(包括sourcemap扳剿,devserver都不應(yīng)該出現(xiàn)在生產(chǎn)的配置中)旁趟。

  • sourcemap 讓開發(fā)更易于調(diào)試

module.exports = {
devtool: 'eval-source-map',//配置生成Source Maps,選擇合適的選項
....
}
}


1080406-20170216173614175-520278059.png
  • 使用ES6語法

webpack2.0增加了對ES6模塊的支持庇绽,無需額外的配置锡搜,并且可以與 AMD 和 CommonJS混用。webpack 2可以分析理解所有的ES6代碼并且只在檢測到是ES6模塊時才使用tree-shaking瞧掺。然而耕餐,只有import導(dǎo)入和export導(dǎo)出的模塊才會被編譯為ES5,如果希望所有的打包文件都編譯為ES5辟狈,你需要使用一個轉(zhuǎn)譯器來處理剩下來的文件肠缔。這里我使用babel。首先安裝babel:

npm install --save-dev babel-core babel-loader babel-preset-es2015
在根目錄下添加.babelrc文件上陕,并添加配置
如果bable的配置仍然為:
{
presets: ['es2015']
}
那么無用的代碼也會被打包(Babel會將ES 6模塊通過commonJs模塊轉(zhuǎn)換輸出桩砰,然后webpack 2就不能進行tree-shaking分析了)。這塊兒大致原理是這樣的释簿。亚隅。。
因此我們將配置文件改為:
{
"presets": [
["es2015", {"modules": false}]
]
}
并且在webpack的配置文件中加入如下loader(此處一定不能用use庶溶,不知道為啥)
{
test: /.js$/,
loader: 'babel-loader', //此處不能用use煮纵,不知道為啥
exclude: /node_modules/ //需要排除的目錄
}

  • 熱加載模塊(HMR)

webpack配置文件中,devServer的“inline”選項會為入口頁面添加“熱加載”功能偏螺,“hot”選項則開啟“熱替換(Hot Module Reloading)”行疏,即嘗試重新加載組件改變的部分(而不是重新加載整個頁面)。如果兩個參數(shù)都傳入套像,當(dāng)資源改變時酿联,webpack-dev-server將會先嘗試HRM(即熱替換),如果失敗則重新加載整個入口頁面。要使用HRM贞让,首先需要在webpack配置文件中配置plugin:

plugins: [
...
new webpack.HotModuleReplacementPlugin() // 熱加載插件
]
到這一步周崭,實際上改變css可以實現(xiàn)hrm,然而js只會刷新整個頁面喳张,index.html直接不刷新了续镇。。销部。不知道為啥摸航。react可以通過react-transform-hrm來搞定。非react框架現(xiàn)在考慮用webpack-dev-middleware 來嘗試一下

  • 生產(chǎn)環(huán)境

通過以上步驟基本的開發(fā)環(huán)境就搭建完畢了舅桩,那么實際上在生產(chǎn)環(huán)境里可能會有其他的要求酱虎,例如分離js與css(目前css是打包到j(luò)s中去的),例如壓縮代碼等江咳。

首先創(chuàng)建一個webpack.production.config.js,然后在package.json中配置修改為:

"scripts": {
"start": "webpack-dev-server",
"build": "set NODE_ENV=production&&webpack --config ./webpack.production.config.js"
}

當(dāng)運行 npm run build 的時候逢净,會設(shè)置環(huán)境變量"NODE_ENV"為"production"。

var prod = process.env.NODE_ENV === 'production' ? true : false;

現(xiàn)在分別介紹幾個常用的插件

1.提取公共模塊插件(webpack內(nèi)置) CommonsChunkPlugin

2.壓縮js插件(webpack內(nèi)置) UglifyJsPlugin

3.分離css文件: ExtractTextPlugin 注意該插件由于和webpack2不兼容歼指,需要指定版本爹土。。在webpack.production.config.js 中的配置參考https://github.com/webpack-contrib/extract-text-webpack-plugin踩身,注意與1.x版本loader的寫法不同胀茵。

1080406-20170220122357960-412737218.png

4.清除文件夾: clean-webpack-plugin

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市挟阻,隨后出現(xiàn)的幾起案子琼娘,更是在濱河造成了極大的恐慌,老刑警劉巖附鸽,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脱拼,死亡現(xiàn)場離奇詭異,居然都是意外死亡坷备,警方通過查閱死者的電腦和手機熄浓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來省撑,“玉大人赌蔑,你說我怎么就攤上這事【癸” “怎么了娃惯?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長肥败。 經(jīng)常有香客問我趾浅,道長愕提,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任潮孽,我火速辦了婚禮揪荣,結(jié)果婚禮上筷黔,老公的妹妹穿的比我還像新娘往史。我一直安慰自己,他們只是感情好佛舱,可當(dāng)我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布椎例。 她就那樣靜靜地躺著,像睡著了一般请祖。 火紅的嫁衣襯著肌膚如雪订歪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天肆捕,我揣著相機與錄音刷晋,去河邊找鬼。 笑死慎陵,一個胖子當(dāng)著我的面吹牛眼虱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播席纽,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼捏悬,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了润梯?” 一聲冷哼從身側(cè)響起过牙,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎纺铭,沒想到半個月后寇钉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡舶赔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年扫倡,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片顿痪。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡镊辕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蚁袭,到底是詐尸還是另有隱情征懈,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布揩悄,位于F島的核電站卖哎,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜亏娜,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一焕窝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧维贺,春花似錦它掂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至垃沦,卻和暖如春客给,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背肢簿。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工靶剑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人池充。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓桩引,卻偏偏與公主長得像,于是被迫代替她去往敵國和親纵菌。 傳聞我的和親對象是個殘疾皇子阐污,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容