如下全部安裝命令的 ‘-D‘ 表明安裝在該文件的devDependencies中
npm的文檔說明:dependencies是運行時依賴,devDependencies是開發時的依賴
css
webpack能夠看作是模塊打包機。webpack-cli封裝了與CLI處理相關的全部代碼。它捕獲選項並將它們發送到webpack編譯器。webpack-dev-server是webpack官方提供的一個小型express服務器, 爲webpack打包生成的資源文件提供web服務。webpack-merge是和用來區分兩個不一樣的環境html
能夠跨平臺設置環境變量vue
@babel/core是轉譯器自己,提供了babel的轉譯API。babel-loader就是調用這些API來完成轉譯js過程的。Babel 7宣佈廢棄babel-preset-es201x而採用新的env插件node
Babel默認只轉換新的JavaScript句法,而不轉換新的API。須要在入口加載@babel/polyfill插件來轉換,能夠解決某些方法在IE的兼容性問題(這種方式是經過向全局對象和內置對象的prototype上添加方法實現的,會形成全局變量污染),在babel7.x版本中使用 :@babel/runtime-corejs2,能夠結合@babel/plugin-transform-runtime, 可避免全局污染。webpack
在轉換 ES2015 語法爲 ECMAScript 5 的語法時,babel 會須要一些輔助函數,例如 _extend。babel 默認會將這些輔助函數內聯到每個 js 文件裏,這樣文件多的時候,項目就會很大。因此 babel 提供了 transform-runtime 來將這些輔助函數「搬」到一個單獨的模塊 babel-runtime 中,這樣作能減少項目文件的大小。web
將類和對象裝飾器編譯爲ES5express
容許解析import() 延遲加載,懶加載
npm
能夠訪問深層嵌套的屬性,能夠不用邏輯與去判斷 // const baz = obj?.foo?.bar?.baz
json
注意: babel7.0後,已經再也不使用@babel/preset-stage-x的預設了, 所需的插件都須要單獨去安裝配置,根據公司的項目須要,能夠選擇性的去配置 :@babel/plugin-*** 這裏不作過多贅述。api
解析vue文件須要安裝這兩個插件
用來在生產環境壓縮js
css-loader處理css,用來解析@import這種語法。sass-loader將sass語言轉換成css, postcss-loader 和 autoprefixer用來爲css的樣式自動添加瀏覽器前綴,mini-css-extract-plugin是提取css文件,再也不以style標籤存放,而是建立link標籤引入,因此再也不須要style-loader。optimize-css-assets-webpack-plugin用來壓縮css
url-loader打包圖片資源,file-loader打包字體等資源
html-webpack-plugin用來打包時自動生成html文件,clean-webpack-plugin打包時會自動清除dist,copy-webpack-plugin用來拷貝靜態資源到打包目錄
npx eslint --init 一鍵配置eslint規範。此外須要安裝babel-eslint工具。建立.eslintignore文件可設置忽略檢測的文件。在webstorm工具中設置eslint,編譯器能夠實時檢測,顯示錯誤
安裝完上述依賴以後,須要根據本身的安裝去配置.babelrc(babel的配置文件)和postcss.config.js。這裏直接附上我本身的配置僅供參考。以下:
{
"presets": [
"@babel/preset-env"
],
"plugins": [
["@babel/plugin-transform-runtime", {
"corejs": 2
}],
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
],
"@babel/plugin-proposal-optional-chaining"
]
}
複製代碼
module.exports = {
plugins: [
require('autoprefixer')
]
}複製代碼
let path = require('path')
let MiniCssExtractPlugin = require('mini-css-extract-plugin') // 提取css公共文件
let { VueLoaderPlugin } = require('vue-loader') //vue-loader 15.x版本之後須要引入
let HtmlWebpackPlugin = require('html-webpack-plugin') //自動生成html
let CopyWebpackPlugin = require('copy-webpack-plugin') //拷貝靜態資源
let { CleanWebpackPlugin } = require('clean-webpack-plugin') //打包前清除dist
let webpack = require('webpack')
module.exports = {
entry: [ path.resolve(__dirname, '../src/main.js') ],
output: {
filename: 'js/[name].[hash:8].js', //打包後的js文件放在js目錄下,添加hash值防止緩存
chunkFilename: 'js/[name].[hash:8].js', // 配合按需加載路由來使用,用來修改打包後的各個JS模塊文件名字,具體請看下方打包後的截圖
path: path.resolve(__dirname, '../dist'), //輸出的目錄
publicPath: '/' //靜態資源cdn的地址
},
stats: { // 本地起服務或者打包時候,清除過多的日誌信息,精簡控制檯信息。
modules: false,
children: false,
chunks: false,
chunkModules: false,
assets: false, //不顯示資源打包信息
},
module: { //轉換規則
rules: [
{
test: /\.vue$/,
exclude: /node_modules/,
use: ['vue-loader']
},
{
test: /\.js$/,
exclude: /node_modules/,
use: ['babel-loader']
},
{
test: /\.(css|scss|sass)$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'sass-loader'
]
},
{
test: /\.(png|jpe?g|svg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 20 * 1024 // 不設置這個的話,打包後的圖片默認是超過8k時,會以base64編碼
name: 'images/[name].[hash:8].[ext]'
}
}
]
},
{
test:/\.(woff|woff2|eot|ttf|otf)$/,
use: [
{
loader: 'file-loader',
options: {
name: 'fonts/[name].[hash:8].[ext]'
}
}
]
},
]
},
resolve: {
extensions: ['.vue', '.js', '.scss', '.json'],// 可以使用戶在引入模塊時不帶擴展名字, 自動解析
alias: { //別名,方便快速查找模塊
'@': path.resolve(__dirname, '../src')
}
},
plugins: [
new VueLoaderPlugin(),
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.resolve(__dirname, '../index.html'),
title: '這是自定義的名字,請隨意',
favicon: path.resolve(__dirname, '../src/images/logon.png'), //瀏覽器標題的圖標
hash: true,
minify: {
removeAttributeQuotes: true, //刪除屬性的引號
collapseWhitespace: true //刪除空白符與摺疊行
}
}),
new CleanWebpackPlugin(),
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../src/assets'),
to: path.resolve(__dirname, '../dist/copyAssets')
}
]),
new MiniCssExtractPlugin({
filename: 'css/[name].[hash:8].css'
}),
new webpack.ProgressPlugin() //顯示打包進度的插件
]
}
複製代碼
let webpack = require('webpack')
let path = require('path')
let merge = require('webpack-merge')
let base = require('./webpack.base.config')
module.exports = merge(base, {
mode: 'development', // 定義環境變量
devtool: 'cheap-module-eval-source-map',
devServer: {
port: 8000, //設置端口
progress: true,// 控制檯顯示百分比,HDM進度
hot: true, // 啓用熱更新,控制檯所有刷新
open: true, // 自動打開瀏覽器
historyApiFallback: true,
contentBase: path.resolve(__dirname, '../dist'),
proxy: {
'/api': { //url中匹配到'/api', 就會把'/api'以前的東西所有替換成target
target: '', // 目標服務器host
changeOrigin: true, // 表示要改變原始host
secure: false, // 默認請求的服務是https的, 而且證書是未認證的,因此須要關閉安全檢測。
clentLogLevel: 'none', //當使用內聯模式(inline mode)時,會在開發工具(DevTools)的控制檯(console)顯示消息,例如:在從新加載以前,在一個錯誤以前,或者 模塊熱替換(Hot Module Replacement) 啓用時。默認值是 info。
pathRewrite: {
'^/api': '' // 重寫請求,源訪問地址中包含'/api'的將會替換爲空
}
}
}
},
plugins: [
new webpack.HotModuleReplacementPlugin(), //熱更新插件
new webpack.NamedChunksPlugin() // 使用此插件熱更新時控制檯會顯示模塊的相對路徑
]
})複製代碼
let merge = require('webpack-merge')
let base = require('./webpack.base.config')
let UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
let OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
module.exports = merge(base, {
mode: 'production',
devtool: 'cheap-module-source-map',
optimization: {
minimizer: [
new UglifyjsWebpackPlugin({ // 生產環境壓縮JS
cache: true, //是否否啓用緩存
parallel: true, //多通道並行處理
sourceMap: false, //生產環境關閉源碼映射
uglifyOptions: {
warnings: false, //清除警告
compress:{
drop_debugger: true, // 清除degugger
drop_console: true //清除全部的console信息
}
}
}),
new OptimizeCssAssetsPlugin() // 生產環境壓縮css
],
splitChunks: { //用於拆分代碼,找到 chunk 中共同依賴的模塊進行「提取」和「分離」到單獨的文件中,減小打包後體積,能夠避免內存溢出的問題。
chunks: 'all'
}
},
performance: { // webpack 的性能提示
hints: 'warning', // 顯示警告信息
maxEntrypointSize: 5 * 1024 * 1024, // 設置入口文件的最大致積爲5M (以字節爲單位)
maxAssetSize: 20* 1024 * 1024, // 設置輸出文件的最大致積爲20M (以字節爲單位)
assetFilter (assetFilename) { // 提供資源文件名的斷言函數
return assetFilename.endsWith('.js') || assetFilename.endsWith('.css')
}
}
})
複製代碼
在package.json文件的scripts中添加以下,而後執行npm run build便可打包
"serve": "cross-env NODE_ENV=development webpack-dev-server --config ./build/webpack.dev.config.js",
"build": "cross-env NODE_ENV=production webpack --config ./build/webpack.prod.config.js"
複製代碼
以上配置是採用webpack4.x+babel7.x版本,自行配置時請注意版本兼容問題。若是您想要升級項目到babel7.0, 文檔中也提供了一個升級工具:執行 npx babel-upgrade--write--install一鍵安裝babel7.0所須要的全部配置,而且會自動將配置寫入package.json和.babelrc文件中。詳情請參考文檔說明。如下是打包後的截圖:
copyAssets是拷貝的靜態資源。爲何打包後的js會有0**,2** 這麼幾個文件呢?這是由於我vue的路由使用了按需加載,每一個頁面都生成本身單獨的js。等須要的時候,纔會去加載這些js的。可是這個0, 1, 2,...等等的文件名字默認是以id命名的,這看起來不友好,並且不太方便排錯,因此須要在引入路由時候,須要使用特殊的註釋語法來提供webpackChunkName,配合output裏面設置的chunkFilename: 'js/[name].[hash:8].js' 來修改文件名,代碼以下:
export default new Router({
mode: 'history',
routes: [
{
path: '',
redirect: '/Home'
},
{
path: '/Home',
name: 'Home',
component: () => import(/* webpackChunkName: 'Home' */ '@/view/Home')
},
{
path: '/Hello',
name: 'Hello',
component: () => import(/* webpackChunkName: 'Hello' */ '@/view/Hello')
}
]
})複製代碼
最終打包後的結果以下,看看,這就舒服多了~