1.安裝nodejs
2. 需要全局和項目安裝webpack和webpack-dev-server
npm install webpack webpack-dev-server -g npm install webpack webpack-dev-server --save-dev
本框架的功能如下:
1、babel babel-folyfill 處理js
2、css、less 自動編譯成css文件並添加前綴
3、less語法編譯
4、圖片處理
5、開發環境頁面自動刷新
6、resolve 解析
7、引用HTML模板
8、css分離
9、打包優化,大文件拆分
10、原生ajax請求(get、post)
11、純原生分頁
文件目錄結構如圖所示:

項目github地址:https://github.com/HelloWoed/webpack-project-demo
說明一下:由於使用了css分離,會導致css背景圖片和html img標簽圖片路徑出錯問題,這里的解決辦法是:css中使用的圖片用assets/static/images中的圖片,css-loader配置的options中url:false,這樣在解析css時就不會處理css圖片路徑,
{
test:/\.less$/,
use: ExtractTextWebpackPlugin.extract({
fallback:'style-loader',
use:[
{
loader:'css-loader',
options:{
url:false,
importLoaders:1
}
},
'postcss-loader',
'less-loader'
],
publicPath: '../css'
}),
exclude: path.resolve(__dirname,'./node_modules')
},
最后將static目錄拷貝到相應的打包目錄(這里使用的是 copy-webpack-plugin 插件)static目錄為你靜態數據目錄
new copyWebpackPlugin([
{
from:__dirname+'/src/assets/static',//打包的靜態資源目錄地址
to:'./static' //打包到dist下面的static
}
]),
package.json配置文件如下:
{
"name": "testwebpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --mode production --watch --progress --display-reasons --color",
"dev": "webpack-dev-server --inline --progress --mode development"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.1.2",
"@babel/preset-env": "^7.1.0",
"autoprefixer": "^9.2.1",
"babel-core": "^6.26.3",
"babel-loader": "^8.0.4",
"babel-polyfill": "^6.26.0",
"clean-webpack-plugin": "^0.1.19",
"css-loader": "^1.0.0",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"file-loader": "^2.0.0",
"html-webpack-plugin": "^3.2.0",
"html-withimg-loader": "^0.1.16",
"less": "^3.8.1",
"less-loader": "^4.1.0",
"postcss-loader": "^3.0.0",
"style-loader": "^0.23.1",
"url-loader": "^1.1.2",
"webpack": "^4.21.0",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.9"
}
}
webpack.config.js文件配置如下:(有很多配置項可根據具體情況設置,不用全部配置)
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
// 拆分css樣式的插件
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const copyWebpackPlugin = require('copy-webpack-plugin');
function resolve (dir) {
return path.join(__dirname, './', dir)
}
console.log(resolve ('abcdefghijklmnop'));
module.exports = {
mode:'development',
// entry:['babel-polyfill','./main.js'],//可以有多個入口文件
entry:{
babelPolyfill:'babel-polyfill',//添加了這個東西,才能完美的將ES6轉碼,否則Babel默認只轉換新的JavaScript句法(syntax),而不轉換新的API,如:Set Map
app:'./main.js',//可以有多個入口文件
},
output:{
path:path.resolve(__dirname,"dist"),//輸出文件路徑 path:path.join(__dirname,"dist","js")
filename:"./js/[name].bundle.js",//"[name].[chunckhash].bundle.js" 輸出的文件名稱
},
devtool: 'inline-source-map',
resolve: {
extensions: ['.js', '.json'],
alias: {
'@': resolve('src'),
}
},
//在webpack4之前,提取公共代碼都是通過一個叫CommonsChunkPlugin的插件來辦到的。到了webpack4以后,內置了一個一模一樣的功能,就是所謂的“優化”
// optimization: { // 提取公共代碼
// splitChunks: {
// cacheGroups: {
// vendor: { // 剝離第三方插件
// test: /node_modules/, // 指定是node_modules下的第三方包
// chunks: 'initial',
// name: 'vendor', // 打包后的文件名,隨意命名
// priority: 10 // 設置優先級,防止和自定義的公共代碼提取時被覆蓋,不進行打包
// },
// utils: { // 抽離自己寫的公共代碼,utils這個名字可以隨意起
// chunks: 'initial',
// name: 'utils', // 任意命名
// minSize: 0 // 只要超出0字節就生成一個新包
// }
// }
// }
// },
performance: {
hints: "warning", // 枚舉
maxAssetSize: 30000000, // 整數類型(以字節為單位)
maxEntrypointSize: 50000000, // 整數類型(以字節為單位)
assetFilter: function(assetFilename) {
// 提供資源文件名的斷言函數
return assetFilename.endsWith('.css') || assetFilename.endsWith('.js');
}
},
module:{
rules:[
{
test:/\.js$/,
exclude: /node_modules/,//有變化了處理,沒有變化則不處理
// include:[resolve('src'), resolve('test')],//需要處理的文件夾
loader:"babel-loader"
},
{
test:/\.css$/,
// loader:"style-loader!css-loader",
use: ExtractTextWebpackPlugin.extract({
// 將css用link的方式引入就不再需要style-loader了
fallback: "style-loader",
use:[
{
loader:'css-loader',
options:{
url:false, //false css中加載圖片的路徑將不會被解析 不會改變
importLoaders:1
}
},
'postcss-loader',
],
publicPath: '../css'
})
// use: [ //以行內樣式style的標簽寫進打包后的html頁面中
// {
// loader: "style-loader"
// },
// {
// loader: "css-loader",
// options: {
// modules: true, // 指定啟用css modules
// localIdentName: '[name]__[local]--[hash:base64:5]' // 指定css的類名格式
// }
// },
// {
// loader: "postcss-loader"
// }
// ]
},
{
test:/\.less$/,
use: ExtractTextWebpackPlugin.extract({
fallback:'style-loader',
use:[
{
loader:'css-loader',
options:{
url:false,
importLoaders:1
}
},
'postcss-loader',
'less-loader'
],
publicPath: '../css'
}),
exclude: path.resolve(__dirname,'./node_modules')
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: "[name].[hash:4].[ext]",
outputPath: "./images",//打包后圖片文件輸出路徑
publicPath:'./images'
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: 'media/[name].[hash:7].[ext]'
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: 'fonts/[name].[hash:7].[ext]'
}
},
{ //頁面中會用到img標簽,img引用的圖片地址也需要一個loader來處理,這樣再打包后的html文件下img就可以正常引用圖片路徑了
test: /\.(htm|html)$/,
use: 'html-withimg-loader'
}
]
},
plugins:[
// 打包前先清空
new CleanWebpackPlugin('dist/') ,
new ExtractTextWebpackPlugin({ //樣式文件單獨打包
filename: "./css/[name].min.css", //指定生成的文件名稱
disable: false, //是否禁用此插件
allChunks: true
}),
new HtmlWebpackPlugin({
template:"./index.html",//本地模板文件的位置,支持加載器(如handlebars、ejs、undersore、html等),如比如 handlebars!src/index.hbs;
filename: './index.html',//輸出文件的文件名稱,默認為index.html,不配置就是該文件名;此外,還可以為輸出文件指定目錄位置(例如'html/index.html')
title: 'Webpack App',//生成的html文檔的標題
chunks:["app"],
inject:true,//1、true或者body:所有JavaScript資源插入到body元素的底部2、head: 所有JavaScript資源插入到head元素中3、false: 所有靜態資源css和JavaScript都不會注入到模板文件中
showErrors:true,//是否將錯誤信息輸出到html頁面中
hash:true,//是否為所有注入的靜態資源添加webpack每次編譯產生的唯一hash值
minify: false,//傳遞 html-minifier 選項給 minify 輸出
favicon: "",//添加特定的 favicon 路徑到輸出的 HTML 文件中。
}),
new copyWebpackPlugin([
{
from:__dirname+'/src/assets/static',//打包的靜態資源目錄地址
to:'./static' //打包到dist下面的static
}
]),
],
devServer: {
publicPath: '/',//
contentBase: path.resolve(__dirname, 'dist'),//此處的路徑必須和輸出output文件的路徑一致 否則無法自動更新,或者是基於output的相對路徑
compress: true,
historyApiFallback: true,//在開發單頁應用時非常有用,它依賴於HTML5 history API,如果設置為true,所有的跳轉將指向index.html
inline: true,//設置為true,當源文件改變時會自動刷新頁面
// grogress: true,
host: 'localhost',// 默認是localhost
port: 9000,//指定用於偵聽請求的端口號
open:true,//當open啟用時,開發服務器將打開瀏覽器。
//hot: true,// 開啟熱更新,開啟熱加載還需在主入口js文件中配置
// openPage:'index.html',//指定在打開瀏覽器時導航到的頁面。
overlay: {//當存在編譯器錯誤或警告時,在瀏覽器中顯示全屏覆蓋,顯示警告和錯誤:
warnings: true,
errors: true
},
proxy: {//代理配置
'/api': {
target: 'http://localhost:3000',
pathRewrite: {'^/api' : ''},//如果不想/api傳遞,我們需要重寫路徑
}
},
}
}
postcss.config.js文件配置如下:
module.exports = {
plugins: [
require('autoprefixer')
]
}
const
path =
require(
"path");
const
HtmlWebpackPlugin =
require(
"html-webpack-plugin");
// 拆分css樣式的插件
const
ExtractTextWebpackPlugin =
require(
'extract-text-webpack-plugin');
const
CleanWebpackPlugin =
require(
'clean-webpack-plugin');
const
copyWebpackPlugin =
require(
'copy-webpack-plugin');
function
resolve (
dir) {
return
path.
join(
__dirname,
'./',
dir)
}
console.
log(
resolve (
'abcdefghijklmnop'));
module.
exports = {
mode:
'development',
// entry:['babel-polyfill','./main.js'],//可以有多個入口文件
entry:{
babelPolyfill:
'babel-polyfill',
//添加了這個東西,才能完美的將ES6轉碼,否則Babel默認只轉換新的JavaScript句法(syntax),而不轉換新的API,如:Set Map
app:
'./main.js',
//可以有多個入口文件
},
output:{
path:path.
resolve(
__dirname,
"dist"),
//輸出文件路徑 path:path.join(__dirname,"dist","js")
filename:
"./js/[name].bundle.js",
//"[name].[chunckhash].bundle.js" 輸出的文件名稱
},
devtool:
'inline-source-map',
resolve: {
extensions: [
'.js',
'.json'],
alias: {
'@'
:
resolve(
'src'),
}
},
//在webpack4之前,提取公共代碼都是通過一個叫CommonsChunkPlugin的插件來辦到的。到了webpack4以后,內置了一個一模一樣的功能,就是所謂的“優化”
// optimization: { // 提取公共代碼
// splitChunks: {
// cacheGroups: {
// vendor: { // 剝離第三方插件
// test: /node_modules/, // 指定是node_modules下的第三方包
// chunks: 'initial',
// name: 'vendor', // 打包后的文件名,隨意命名
// priority: 10 // 設置優先級,防止和自定義的公共代碼提取時被覆蓋,不進行打包
// },
// utils: { // 抽離自己寫的公共代碼,utils這個名字可以隨意起
// chunks: 'initial',
// name: 'utils', // 任意命名
// minSize: 0 // 只要超出0字節就生成一個新包
// }
// }
// }
// },
performance: {
hints:
"warning",
// 枚舉
maxAssetSize:
30000000,
// 整數類型(以字節為單位)
maxEntrypointSize:
50000000,
// 整數類型(以字節為單位)
assetFilter
:
function(
assetFilename) {
// 提供資源文件名的斷言函數
return
assetFilename.
endsWith(
'.css') ||
assetFilename.
endsWith(
'.js');
}
},
module:{
rules:[
{
test:
/
\.
js
$
/,
exclude:
/node_modules/,
//有變化了處理,沒有變化則不處理
// include:[resolve('src'), resolve('test')],//需要處理的文件夾
loader:
"babel-loader"
},
{
test:
/
\.
css
$
/,
// loader:"style-loader!css-loader",
use:
ExtractTextWebpackPlugin.
extract({
// 將css用link的方式引入就不再需要style-loader了
fallback:
"style-loader",
use:[
{
loader:
'css-loader',
options:{
url:
false,
//false css中加載圖片的路徑將不會被解析 不會改變
importLoaders:
1
}
},
'postcss-loader',
],
publicPath:
'../css'
})
// use: [ //以行內樣式style的標簽寫進打包后的html頁面中
// {
// loader: "style-loader"
// },
// {
// loader: "css-loader",
// options: {
// modules: true, // 指定啟用css modules
// localIdentName: '[name]__[local]--[hash:base64:5]' // 指定css的類名格式
// }
// },
// {
// loader: "postcss-loader"
// }
// ]
},
{
test:
/
\.
less
$
/,
use:
ExtractTextWebpackPlugin.
extract({
fallback:
'style-loader',
use:[
{
loader:
'css-loader',
options:{
url:
false,
importLoaders:
1
}
},
'postcss-loader',
'less-loader'
],
publicPath:
'../css'
}),
exclude:
path.
resolve(
__dirname,
'./node_modules')
},
{
test:
/
\.
(
png
|
jpe
?
g
|
gif
|
svg
)(
\?
.
*
)
?
$
/,
loader:
'url-loader',
options: {
limit:
10000,
name:
"[name].[hash:4].[ext]",
outputPath:
"./images",
//打包后圖片文件輸出路徑
publicPath:
'./images'
}
},
{
test:
/
\.
(
mp4
|
webm
|
ogg
|
mp3
|
wav
|
flac
|
aac
)(
\?
.
*
)
?
$
/,
loader:
'url-loader',
options: {
limit:
10000,
name:
'media/[name].[hash:7].[ext]'
}
},
{
test:
/
\.
(
woff2
?
|
eot
|
ttf
|
otf
)(
\?
.
*
)
?
$
/,
loader:
'url-loader',
options: {
limit:
10000,
name:
'fonts/[name].[hash:7].[ext]'
}
},
{
//頁面中會用到img標簽,img引用的圖片地址也需要一個loader來處理,這樣再打包后的html文件下img就可以正常引用圖片路徑了
test:
/
\.
(
htm
|
html
)
$
/,
use:
'html-withimg-loader'
}
]
},
plugins:[
// 打包前先清空
new
CleanWebpackPlugin(
'dist/') ,
new
ExtractTextWebpackPlugin({
//樣式文件單獨打包
filename:
"./css/[name].min.css",
//指定生成的文件名稱
disable:
false,
//是否禁用此插件
allChunks:
true
}),
new
HtmlWebpackPlugin({
template:
"./index.html",
//本地模板文件的位置,支持加載器(如handlebars、ejs、undersore、html等),如比如 handlebars!src/index.hbs;
filename:
'./index.html',
//輸出文件的文件名稱,默認為index.html,不配置就是該文件名;此外,還可以為輸出文件指定目錄位置(例如'html/index.html')
title:
'Webpack App',
//生成的html文檔的標題
chunks:[
"app"],
inject:
true,
//1、true或者body:所有JavaScript資源插入到body元素的底部2、head: 所有JavaScript資源插入到head元素中3、false: 所有靜態資源css和JavaScript都不會注入到模板文件中
showErrors:
true,
//是否將錯誤信息輸出到html頁面中
hash:
true,
//是否為所有注入的靜態資源添加webpack每次編譯產生的唯一hash值
minify:
false,
//傳遞 html-minifier 選項給 minify 輸出
favicon:
"",
//添加特定的 favicon 路徑到輸出的 HTML 文件中。
}),
new
copyWebpackPlugin([
{
from:__dirname+
'/src/assets/static',
//打包的靜態資源目錄地址
to:
'./static'
//打包到dist下面的static
}
]),
],
devServer: {
publicPath:
'/',
//
contentBase:
path.
resolve(
__dirname,
'dist'),
//此處的路徑必須和輸出output文件的路徑一致 否則無法自動更新,或者是基於output的相對路徑
compress:
true,
historyApiFallback:
true,
//在開發單頁應用時非常有用,它依賴於HTML5 history API,如果設置為true,所有的跳轉將指向index.html
inline:
true,
//設置為true,當源文件改變時會自動刷新頁面
// grogress: true,
host:
'localhost',
// 默認是localhost
port:
9000,
//指定用於偵聽請求的端口號
open:
true,
//當open啟用時,開發服務器將打開瀏覽器。
//hot: true,// 開啟熱更新,開啟熱加載還需在主入口js文件中配置
// openPage:'index.html',//指定在打開瀏覽器時導航到的頁面。
overlay: {
//當存在編譯器錯誤或警告時,在瀏覽器中顯示全屏覆蓋,顯示警告和錯誤:
warnings:
true,
errors:
true
},
proxy: {
//代理配置
'/api'
: {
target:
'http://localhost:3000',
pathRewrite: {
'^/api'
:
''},
//如果不想/api傳遞,我們需要重寫路徑
}
},
}
}
