- webpack是什么?
webpack是一個前端資源加載/打包工具,有兩種依賴聲明方式:同步和異步。將依賴分割成多個節點,然后每個節點形成一個新的文件塊。經過優化后的文件塊樹,會以一個個文件形式分發出去(僅僅打包成一個大文件形式是很低效的)。 - webpack有哪些優點?
- 分離現有依賴樹,按需加載
- 高效保證第一次加載
- 靜態資源模塊化
- 第三方庫模塊化加載
- 實現加載器幾乎所有環節的可配置性
- 安裝與使用
// 安裝
npm install -g webpack // 全局安裝方式
npm install webpack // 本地安裝(建議,聲明webpack依賴創建package.json)
// 使用
npm init // 將產生一個package.json依賴配置文件
npm install // 按配置方式安裝依賴
webpack -p // webpack打包
webpack --watch // 自動監聽變化,動態編譯
- webpack中的配置項與常用node模塊使用
entry: 應用程序開始執行和webpack開始打包的入口文件
output: webpack輸出結果的相關選項
path: 所有輸出文件的目標路徑
filename: 輸出文件
publicPath: 輸出解析文件的目錄
library: 導出庫的名稱
libraryTarget:導出庫的類型
resolve: 解析模塊請求的選項
module: 模塊配置
test/include: 具有相同的作用,都是必須匹配選項
exclude: 必不匹配選項(優先于test和include)
// - 只在 test 和 文件名匹配 中使用正則表達式
// - 在 include 和 exclude 中使用絕對路徑數組
// - 盡量避免 exclude,更傾向于使用 include
plugins: 附加插件列表
- webpack 1 config實例
const path = require('path');
// 引入路徑模式匹配模塊,用于多文件
const glob = require('glob');
const webpack = require('webpack');
// 分離css單獨打包
const ExtractTextPlugin = require('extract-text-webpack-plugin');
// 創建index入口文件
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 獲取webpack.config.js同級目錄作為項目根目錄
const ROOT_PATH = path.resolve(__dirname);
// 獲取所有入口文件
let getEntry = function(gPath) {
// 需要單獨打包的第三方庫作為單獨的入口
let entries = {
jquery: ['jquery'],
react: ['react', 'react-dom'],
vendor: ['./index.js']
};
glob.sync(gPath).forEach(function(entry) {
let pname = entry.split('/').splice(3).join('/').split('.')[0];
entries[pname] = [entry];
});
return entries;
};
let isProduction = process.env.NODE_ENV === 'production';
let entries = getEntry('./src/views/**/*.jsx');
let chunks = Object.keys(entries);
const webpack_config = {
// 頁面入口文件配置
entry: entries,
// 入口文件輸出配置
output: {
// 指定編譯后代碼位置
// path: path.resolve(ROOT_PATH, 'dist'),
path: path.resolve(ROOT_PATH), // 以根路徑部署,指定當前項目路徑為根路徑
// 打包JavaScript文件及其依賴文件,并指定生成文件的文件名
filename: isProduction ? 'assets/js/[name].min.js' : 'assets/js/[name].[hash].js',
// publicPath: '/dist/',
publicPath: '/', // 以根路徑部署,指定當前項目路徑為根路徑
chunkFilename: 'chunk/[name].chunk.js'
},
module: {
// 加載器模塊配置
loaders: [
// .jsx babel-loader編譯處理
{ test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel', query: { presets: ['es2015', 'react'] } },
// .scss css-loader!sass-loader這里注意,中間用!鏈式loader,從右向左依次執行
{ test: /\.scss$/, loader: ExtractTextPlugin.extract('style-loader', 'css-loader!sass-loader') },
// images(.png|jpg|gif|svg) url-loader處理,小于10kb的轉為base64
{ test: /\.(png|jpg|gif)$/, loader: 'url-loader', query: {
limit: 8096,
name: isProduction ? 'assets/images/[name].[ext]' : 'assets/images/[name].[hash].[ext]'
}},
{
//文件加載器,處理文件靜態資源
test: /\.(woff|woff2|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'file-loader',
query: {
limit: 8096,
name: isProduction ? 'assets/fonts/[name].[ext]' : 'assets/fonts/[name].[hash].[ext]'
}
}
]
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery', // 使jquery變成全局變量,這樣就不用在文件中require了
jQuery: 'jquery',
React: 'react',
ReactDOM: 'react-dom',
classNames: 'classnames'
}),
// 類庫統一打包生成一個文件
new webpack.optimize.CommonsChunkPlugin({
// 頁面以倒序引用
name: ['jquery', 'react', 'vendor'],
filename: isProduction ? 'assets/js/[name].min.js' : 'assets/js/[name].[hash].min.js',
minChunks: 3 // 提取使用3次以上的模塊打包到vendor里
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new ExtractTextPlugin(isProduction ? 'assets/css/[name].css' : 'assets/css/[name].[hash].css')
],
devtool: isProduction ? null : 'source-map',
// 熱部署
devServer: {
inline: true,
port: 3000
}
};
// 生成HTML文件
chunks.forEach(function(pname) {
// 過濾掉提取的公共庫和使用的第三方庫
if(pname == 'vendor' || pname == 'react' || pname == 'jquery') {
return;
}
let config = {
favicon: './src/images/fav.ico',
title: '默認頁面title', // 如果模板文件中設置,這里將實效
filename: pname + '.html',
template: './template.html',
inject: 'body',
minify: {
removeComments: true,
collapseWhitespace: false
},
cache: true,
chunksSortMode: 'dependency' // 指定引用順序
};
// 指定HTML中引入的scripts
if(pname in webpack_config.entry) {
config.chunks = ['jquery', 'react', 'vendor', pname];
if(isProduction) {
config.hash = false;
}
}
console.log(config);
webpack_config.plugins.push(new HtmlWebpackPlugin(config));
});
module.exports = webpack_config;
// 更多詳情請參看:https://doc.webpack-china.org/configuration/