代碼地址:https://github.com/cheer4chai/webpack-learning
仿照vue-cli開發(fā)這個工具的目的是了解webpack的基本設(shè)置搓侄,以及vue-cli的工作原理
Series1.簡單的打包構(gòu)建功能
webpack的配置很簡單:?
設(shè)置好入口文件:entry词顾,輸出文件:output
// webpack.config.js
module.exports = {
????entry: {
????????bundle1:?'./main1.js',
????????bundle2:?'./main2.js'
????},
????output: {
????????filename:?'[name].js'
????},
????module: {
????????loaders: [{
????????????test: /\.css$/,
????????????loader:?'style-loader!css-loader'
????????}]
????}
}
最終文件目錄:
我們發(fā)現(xiàn)webpack把main1.js和main2.js分別打包為了bundle1和bundle2伤为,main.css也打包到了bundle文件中蠢棱,這樣我們就初步打包成功了赊窥。
Series2.使用loader將less/css文件打包
如果在webpack中需要將less/css等一些非js文件打包至目標(biāo)文件時臊旭,我們就需要用到webpack的特性之一:loader
其實(shí)只要在webpack的配置文件中加入module字段就可以了箩退,代碼如下
let?path = require('path')
let?webpack = require('webpack');
module.exports = {
????entry:?'./src/entry.js',
????devtool:?'inline-source-map',
????output: {
????????path: path.join(__dirname,?'/dist'),
????????filename:?'bundle.js',
????????publicPath:?'/dist/'
????},
????devServer: {
????????contentBase: path.join(__dirname,?"./"),
????????hot:?true,
????},
????module: {
????????loaders: [{
????????????????test: /\.css$/,
????????????????loader:?"style-loader!css-loader"
????????????},
????????????{
????????????????test: /\.less$/,
????????????????loader:?"style-loader!css-loader!less-loader"
????????????}
????????]
????}
}
另外值得一提的是loader是從右到左的鏈?zhǔn)讲僮骼胙缟系腸ss文件,是先經(jīng)過css-loader處理滋戳,再經(jīng)過style-loader處理喊括,才能轉(zhuǎn)化為所需要的打包格式
Series3.使用webpack-dev-server在線瀏覽效果
當(dāng)使用vue-cli的時候我們會想胧瓜,當(dāng)運(yùn)行npm run dev的時候他是怎么生成一個本地的文件的呢,其實(shí)就是用了webpack-dev-server這一個插件郑什,在本地用nodejs生成了一個服務(wù)器府喳,代理了在內(nèi)存中自動生成的靜態(tài)頁面钝满。話不多說,安裝了這個插件之后(yarn add webpack-dev-server)弯蚜,只要在項目目錄下執(zhí)行webpack-dev-server命令,訪問本地localhost:8080就可以看到這個頁面了路鹰。
但是這個時候當(dāng)我們修改了一個文件之后還需要重新用webpack編譯收厨,再刷新頁面再能看到更改內(nèi)容,那么有什么可以解決這個問題嗎雁竞?沒錯拧额,這個時候我們就需要熱重載插件:HotModuleReplacementPlugin。其實(shí)也很簡單进栽,只要在webpack的plugins內(nèi)加入這個組件捎拯,另外在devServer中配置hot為true(或者運(yùn)行的時候執(zhí)行--hot命令),就可以實(shí)現(xiàn)熱重載了祸泪。
還需要一提的是HtmlWebpackPlugin插件建芙,這個插件可以自動生成一個HTML文件,vue-cli最終的html文件就是該文件生成的右蒲,因此我們還需要這個插件去自動生成一個html文件引用output的js文件赶熟,并打開
讓我們來看一下如何配置這幾個東西:
let?path = require('path')
let?webpack = require('webpack');
let?HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
????entry:?'./src/entry.js',
????devtool:?'inline-source-map',
????output: {
????????path: path.join(__dirname,?'dist'),
????????filename:?'bundle.js',
????????publicPath:?'/'
????},
????devServer: {
????????hot:?true,
????????compress:?true,
????????publicPath:?'/'
????},
????module: {
????????loaders: [{
????????????????test: /\.css$/,
????????????????loader:?"style-loader!css-loader"
????????????},
????????????{
????????????????test: /\.less$/,
????????????????loader:?"style-loader!css-loader!less-loader"
????????????}
????????]
????},
????plugins: [
????????new?webpack.HotModuleReplacementPlugin(),?// 熱加載
????????new?HtmlWebpackPlugin(),
????]
}
文件目錄如下:
在根目錄下運(yùn)行webpack-dev-server映砖,我們就可以在本地看到已經(jīng)打包后的頁面了
Series4.使用webpack-merge分別設(shè)置webpack的dev及prod模式
因?yàn)樵谌粘i_發(fā)中,我們往往會需要開發(fā)和生產(chǎn)兩種環(huán)境,而這兩個環(huán)境的webpack配置有相同的地方劳澄,又有不同的地方蜈七,這個時候我們需要用的webpack-merge來將wepack的配置分成兩個模式,類似于vue-cli那樣砂缩,分為三個文件:base/dev/build狡相,分別保存共用設(shè)置、開發(fā)用設(shè)置和生產(chǎn)設(shè)置。
文件如下:
//webpack.base.config
let?path = require('path')
module.exports = {
????entry: {
????????index:?'./src/main.js'
????},
????devtool:?'inline-source-map',
????output: {
????????path: path.join(__dirname,?'dist'),
????????filename:?'bundle.js',
????????publicPath:?'/'
????},
????resolve: {
????????extensions: ['.js',?'.vue',?'.json'],
????????alias: {
????????????'vue$':?'vue/dist/vue.esm.js'
????????}
????},
????module: {
????????loaders: [{
????????????????test: /\.vue$/,
????????????????loader:?'vue-loader'
????????????}, {
????????????????test: /\.css$/,
????????????????loader:?"style-loader!css-loader"
????????????},
????????????{
????????????????test: /\.less$/,
????????????????loader:?"style-loader!css-loader!less-loader"
????????????}
????????]
????}
}
//webpack.dev.config
let?path = require('path')
let?webpack = require('webpack');
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.config')
let?HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = merge(baseWebpackConfig, {
????devServer: {
????????hot:?true,
????????compress:?true,
????????publicPath:?'/'
????},
????plugins: [
????????new?webpack.HotModuleReplacementPlugin(),?// 熱加載
????????new?HtmlWebpackPlugin({
????????????filename:?'index.html',
????????????template:?'index.html',
????????????inject:?true
????????})
????]
})
在生產(chǎn)模式中,為了可以生成更小的文件单绑,已經(jīng)實(shí)現(xiàn)js的按需引用搂橙,我們配置webpack的CommonsChunkPlugin以及UglifyJsPlugin,其中chunk可以將頁面中引用的第三方庫單獨(dú)打包区转,而uglify顧名思義废离,則是壓縮代碼需要的插件,詳細(xì)的配置如下:
//webpack.build.config
let?path = require('path')
let?webpack = require('webpack');
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.config')
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = merge(baseWebpackConfig, {
????entry: {
????????index:?'./src/main.js',
????????vendor: ['jquery',?'vue']
????},
????output: {
????????path: path.join(__dirname,?'dist'),
????????filename: path.join('static',?'js/[name].[chunkhash].js'),
????????chunkFilename: path.join('static',?'js/[id].[chunkhash].js')
????},
????plugins: [
????????new?webpack.optimize.UglifyJsPlugin({
????????????compress: {
????????????????warnings:?false
????????????},
????????????sourceMap:?false,
????????????parallel:?true
????????}),
????????new?HtmlWebpackPlugin({
????????????filename:?'index.html',
????????????template:?'index.html',
????????????inject:?true,
????????????minify: {
????????????????removeComments:?true,
????????????????collapseWhitespace:?true,
????????????????removeAttributeQuotes:?true
????????????????????// more options:
????????????????????// https://github.com/kangax/html-minifier#options-quick-reference
????????????},
????????}),
????????new?webpack.optimize.CommonsChunkPlugin({
????????????name:?'ventor',
????????????minChunks: Infinity
????????})
????]
})
目錄結(jié)構(gòu)如下圖:
Series4.配置vue文件編譯
當(dāng)我們需要向vue-cli一樣,將vue都編譯成最終的js文件的時候肖方,我們需要一個新的loader:vue-loader,另外為了讓webpack可以引入template俯画,我們還需要在webpack中配置resolve字段
改動的代碼如下:
//webpack.dev.config
let?path = require('path')
let?webpack = require('webpack');
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.config')
let?HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = merge(baseWebpackConfig, {
????devServer: {
????????hot:?true,
????????compress:?true,
????????publicPath:?'/'
????},
????plugins: [
????????new?webpack.HotModuleReplacementPlugin(),?// 熱加載
????????new?HtmlWebpackPlugin({
????????????filename:?'index.html',
????????????template:?'index.html',
????????????inject:?true
????????})
????]
})
//webpack.build.config
let?path = require('path')
let?webpack = require('webpack');
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.config')
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = merge(baseWebpackConfig, {
????entry: {
????????index:?'./src/main.js',
????????vendor: ['jquery',?'vue']
????},
????output: {
????????path: path.join(__dirname,?'dist'),
????????filename: path.join('static',?'js/[name].[chunkhash].js'),
????????chunkFilename: path.join('static',?'js/[id].[chunkhash].js')
????},
????plugins: [
????????new?webpack.optimize.UglifyJsPlugin({
????????????compress: {
????????????????warnings:?false
????????????},
????????????sourceMap:?false,
????????????parallel:?true
????????}),
????????new?HtmlWebpackPlugin({
????????????filename:?'index.html',
????????????template:?'index.html',
????????????inject:?true,
????????????minify: {
????????????????removeComments:?true,
????????????????collapseWhitespace:?true,
????????????????removeAttributeQuotes:?true
????????????????????// more options:
????????????????????// https://github.com/kangax/html-minifier#options-quick-reference
????????????},
????????}),
????????new?webpack.optimize.CommonsChunkPlugin({
????????????name:?'ventor',
????????????minChunks: Infinity
????????})
????]
})
項目目錄如下圖:
?如圖烹骨,我們已經(jīng)實(shí)現(xiàn)了一個簡單的類vue-cli構(gòu)建工具。詳細(xì)的代碼可以去我的github看:https://github.com/cheer4chai/webpack-learning吨岭,如果能幫助到你峦树,煩請點(diǎn)個star~