webpack已是前端開發必不可少的神器了;css
1、#先看看他的核心功能,爲何用他?#html
1.打包:能夠把多個Javascript文件打包成一個文件,減小服務器壓力和下載帶寬。前端
2.轉換:把拓展語言轉換成爲普通的JavaScript,讓瀏覽器順利運行。node
3.優化:前端變的愈來愈複雜後,性能也會遇到問題,而WebPack也開始肩負起了優化和提高性能的責任。react
4.Webpack在生產環境中有一個重要的做用就是減小http的請求數jquery
以上三點便是它=他的核心做用。webpack
2、webpack(當下最新版4.8.3)安裝及環境配置web
webpack這傢伙更新甚快,因此不一樣版本的webpack所使用的命令也幾乎各不相同npm
1.全局安裝webpack npm i webpack -gjson
2.進入項目文件夾,初始化項目,爲了生成pake.json文件;npm init 持續回車便可
3.安裝webpack的依賴node_modules; npm i -D webpack
4.全局安裝webpack-cli;npm i webpack-cli -g
5.設置默認開發環境,設置mode(模式),指定是「開發環境(production)」仍是「生產環境(development)」; 固然在持續開發中,得優先設置開發環境;webpack --mode development;
6.之後打包便可輸入webpack --mode development;可是明顯每次這樣輸入繁瑣至極; 在pake.json文中的script下配置 "dev":"webpack --mode development" 和 "build":"webpack --mode production";
輸入npm run dev便可打包到項目自動生成的dist文件夾中;npm run build打包生產環境;
7.全部的開發文件必須在src文件夾下,由於webpack4默認的入口文件夾就是src;
注意:
一、webpack-cli必需要全局安裝,不然不能使用webpack指令;
二、webpack也必需要全局安裝,不然也不能使用webpack指令。
三、webpack4.x中webpack.config.js這樣的配置文件不是必須的。
四、默認入口文件是./src/index.js,默認輸出文件./dist/main.js。
3、配置webpack.config.js| webpack-cli init
Will your application have multiple bundles? No // 單入口 string, 多頁面 object
2. Which module will be the first to enter the application? [example: './src/index'] ./src/index // 程序入口
3. What is the location of "app"? [example: "./src/app"] './src/index' // 程序主文件
4. Which folder will your generated bundles be in? [default: dist]: // 輸出目錄,默認 dist
5. Are you going to use this in production? No // (Yes 第9步默認'config', No 則爲 'prod')
6. Will you be using ES2015? Yes // 會添加 ES6 => ES5 的配置
7. Will you use one of the below CSS solutions? CSS // 選一種樣式語言,會生成對應的 loader 配置
8. If you want to bundle your CSS files, what will you name the bundle? (press enter to skip) // 回車跳過
9. Name your 'webpack.[name].js?' [default: 'config']: // webpack.config.js
Congratulations! Your new webpack configuration file has been created!
複製代碼
webpack.config.js一覽
// 從依賴中引入path
const path = require('path');
const uglify = require('uglifyjs-webpack-plugin');//JS壓縮插件,簡稱uglify
const htmlPlugin= require('html-webpack-plugin');//html打包
// const extractTextPlugin = require('exrract-text-plugin');//extract-text-webpack-plugin將CSS文件分離出來
// __dirname是node.js的全局變量,它指向當前執行腳本所在的目錄。
var website = {
publicPath:"http://localhost:5252/"
}
module.exports = {
devtool: 'eval-source-map',
// entry:__dirname + '/src/main.js',
entry:{
main:'./src/main.js'
},
output:{
//打包的路徑文件夾
path:path.resolve(__dirname,'dist'),//__dirname 表示當前文件所在的目錄的絕對路徑,path.resolve()方法將一系列路徑或路徑段解析爲絕對路徑
//或者這樣寫
// filename:'[name].js'//filename:是打包後的文件名稱
// filename:'[name].[chunkHash:2].js'//每次打包都會引入最新的.js,防止瀏覽器緩存
},
//模塊:例如解讀CSS,圖片如何轉換,壓縮
module:{
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
//或者loader: [ 'style-loader', 'css-loader' ]
//或者:use:[
// {loader:'style-loader'},
// {loader:'css-loader'}
// ]
},
{
test:/\.(png|jpg|gif)/,
use:[{
loader:'url-loader',
options:{
limit:500000
}
}]
}
]
},
//插件,用於生產模版和各項功能
plugins:[
new uglify(),
new htmlPlugin({
minify:{
removeAttributeQuotes:true
},
hash:true,
template:'./src/index.html'
})
// new extractTextPlugin("./css/index.css")//配置分離後的路勁
],
mode:'development',
//配置webpack開發服務功能
devServer: {
//設置基本目錄結構
contentBase: "./dist",//本地服務器所加載的頁面所在的目錄 || contentBase:path:path.resolve(__dirname,'dist')
//服務器的IP地址,可使用IP也可使用localhost
host:'localhost',
//服務端壓縮是否開啓
compress:true,
//配置服務端口號
port:5252,
historyApiFallback: true,//不跳轉
inline: true//實時刷新
}
}
複製代碼
3、webpack:服務和熱更新
安裝服務npm install webpack-dev-server –save-dev 並在page.json中 設置 scripts": { "server":"webpack-dev-server" },
熱更新:webpack-dev-server 提供了兩種模式用於自動刷新頁面: npm run server; npm start使用此命令在pake.json中scrpts中設置: "start": "webpack && webpack-dev-server --hot --inline"
3、loaders(webpack的核心):
全部的Loaders都須要在npm中單獨進行安裝,並在webpack.config.js裏進行配置
1.Loaders的配置型:
test:用於匹配處理文件的擴展名的表達式,這個選項是必須進行配置的;
use:loader名稱,就是你要使用模塊的名稱,這個選項也必須進行配置,不然報錯
include/exclude:手動添加必須處理的文件(文件夾)或屏蔽不須要處理的文件(文件夾)(可選);
query:爲loaders提供額外的設置選項(可選)。
4、文件壓縮打包 1.css文件壓縮,能夠在入口文件index.js中導入,將其壓縮到dist下的js文件中;
index.js 寫入 import css from '.././css/index.css'
2.css中的圖片路勁問題:
很顯然,打包後的圖片是404; 因此解決方法是要安裝url-loader 和 file-loader;
npm install --save-dev file-loader url-loader
file-loader:解決引用路徑的問題,拿background樣式用url引入背景圖來講,咱們都知道,webpack最終會將各個模塊打包成一個文件,所以咱們樣式中的url路徑是相對入口html頁面的,而不是相對於原始css文件所在的路徑的。這就會致使圖片引入失敗。這個問題是用file-loader解決的,file-loader能夠解析項目中的url引入(不只限於css),根據咱們的配置,將圖片拷貝到相應的路徑,再根據咱們的配置,修改打包後文件引用路徑,使之指向正確的文件。
url-loader:若是圖片較多,會發不少http請求,會下降頁面性能。這個問題能夠經過url-loader解決。url-loader會將引入的圖片編碼,生成dataURl。至關於把圖片數據翻譯成一串字符。再把這串字符打包到文件中,最終只須要引入這個文件就能訪問圖片了。固然,若是圖片較大,編碼會消耗性能。所以url-loader提供了一個limit參數,小於limit字節的文件會被轉爲DataURl,大於limit的還會使用file-loader進行copy。
url-loader封裝了file-loader。url-loader不依賴於file-loader,即便用url-loader時,只須要安裝url-loader便可,不須要安裝file-loader,由於url-loader內置了file-loader。
3.css文件分離
安裝extractTextPlugin; npm install extract-text-webpack-plugin@next --save-dev;
const extractTextPlugin = require("extract-text-webpack-plugin");
**注意:**最新版的webpack要安裝對應升級版的分離插件,因此要加上@next;
安裝完在webpack.config.js中引入::const extractTextPlugin = require('extract-text-webpack-plugin');
安裝完以後,還得在webpack.config.js中設置加載項:
// use: [
// { loader: 'style-loader', options: { sourceMap: true } },
// { loader: 'css-loader' }
// ]
// css分離:
替換上面的以下:::
use: extractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
複製代碼
設置Plugins: new extractTextPlugin('/css/index.css')設置打包後的文件路勁
npm run dev後能夠看見dist文件夾下自動生成css;
4.css文件分離後,會致使css中的背景圖片路勁不對;
解決方式是: 在webpack.conifg.js中全局聲明一個ip屬性:
var website ={
publicPath:"http://localhost:5200/"//你的本機ip地址,或自定義的server端口
}
而後再output(輸出對象)中,調用全局變量設置的屬性publicPath;實際是改其相對路徑爲絕對路勁
publicPath:website.publicPath
在進行打包便可找對路勁
複製代碼
5.處理html中的圖片:路勁及文件打包
安裝到生產環境中:
npm install html-withimg-loader --save
在webpack.config.js中配置loader:
{
test: /\.(htm|html)$/i,
use:[ 'html-withimg-loader']
}
而後進行打包,能夠發現圖片路勁正確,並被打包
複製代碼
6.less文件打包::: 安裝less和less-loader npm i less less-loader -D
首先:在src目錄下新建less文件;
次之,在入口文件js中引入less文件;
import less from '.././less/index.less';
而後再webpack.config.js中配置less-loader:
use: [
{loader:'css-loader'},
{loader:'less-loader'} //在js中分離less文件到css中;
]
複製代碼
7.jslabel轉換::: cnpm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react
在webpack.config.js 中配置bable
{
test:/\.(jsx|js)$/,
use:{
loader:'babel-loader',
options:{
presets:[
"es2015","react"
]
}
},
exclude:/node_modules/
}
複製代碼
如今網絡上已經不流行babel-preset-es2015,如今官方推薦使用的是babel-preset-env,
npm install --save-dev babel-preset-env
新建.babelrc文件,在裏面的配置便可
{
"presets":["react","env"]
}
複製代碼
基本的最終webpack.config.js配置
// 在webpack.config.js裏引入必須使用require,不然會報錯的;
const webpack = require('webpack');//引入webpack自帶的插件包,在plugins中調用便可
const path = require('path');//引入node的path模塊(node的path 模塊提供了一些用於處理文件路徑的小工具)
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');//此乃壓縮JS的插件,簡稱uglify
const HtmlWebpackPlugin = require('html-webpack-plugin');//此乃壓縮html的插件
const extractTextPlugin = require('extract-text-webpack-plugin');//以前將css文件打包到了js文件中,沒有將其分離出來,因此用此插件能夠單獨提取css和less
const glob = require('glob');//引入Node.js 中的全局對象是 global;node的glob模塊容許你使用*等符號,來寫一個glob規則;https://blog.csdn.net/tangxiaolang101/article/details/53931145
const PurifyCSSPlugin = require('purifycss-webpack');//PurifyCSS插件能夠大大減小CSS冗餘
// const entry = require(./webpack_config/entry_webpack.js);
// 處理css文件圖片路勁問題
var website ={
publicPath:"http://localhost:5200/"
}
// if(process.env.type== "build"){
// var website={
// publicPath:"http://localhost:5200/"
// }
// }else{
// var website={
// publicPath:"http://localhost:5200/"
// }
// }
// console.log( encodeURIComponent(process.env.type));
module.exports = {
devtool: 'eval-source-map',
entry: {
main:'./src/js/index.js'
},
// entry:entry.path,
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath:website.publicPath// 處理css文件圖片路勁問題 調用全局變量設置的屬性publicPath;實際是改其相對路徑爲絕對路勁
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: ['env']
}
},
{
test: /\.css$/,
// use: [
// { loader: 'style-loader', options: { sourceMap: true } },
// { loader: 'css-loader' }
// ]
// css分離:
use: extractTextPlugin.extract({
use: [
{loader:'css-loader'},
{loader:'less-loader'}
],
fallback: "style-loader",
})
},
{
test:/\.(png|jpg|gif)/ ,
use:[{
loader:'url-loader',
options:{
limit:5000,
outputPath:'img/'//outputPath屬性表示輸出打包後的文件路勁
}
}]
},
// 配置解決html中的 img標籤圖片路勁404問題
{
test: /\.(htm|html)$/i,
use:[ 'html-withimg-loader']
},
{
test: /\.less$/,
use: [
{loader: 'style-loader'},
{loader:'css-loader'},
{loader:'less-loader'}
]
},
{
test:/\.(jsx|js)$/,
use:{
loader:'babel-loader',
options:{
presets:[
"es2015","react"
]
}
},
exclude:/node_modules/
},
{
test:/\.(jsx|js)$/,
use:{
loader:'babel-loader',
},
exclude:/node_modules/
}
// {
// watchOptions:{
// //檢測修改的時間,以毫秒爲單位
// poll:1000,
// //防止重複保存而發生重複編譯錯誤。這裏設置的500是半秒內重複保存,不進行打包操做
// aggregateTimeout:500,
// //不監聽的目錄
// ignored:/node_modules/,
// }
// }
]
},
plugins: [
new UglifyJSPlugin(),
new extractTextPlugin('/css/index.css'),
new HtmlWebpackPlugin({
minify:{
removeAttributeQuotes:true
},
hash:true,
template:'./src/html/index.html',
filename:'html/index.html'
}),
new HtmlWebpackPlugin({
template:'./src/html/oop.html',
filename:'html/oop.html'
}),
new PurifyCSSPlugin({
// Give paths to parse for rules. These should be absolute!
paths: glob.sync(path.join(__dirname, 'src/*.html')), }),
// ProvidePlugin是webpack自帶的插件,能夠用此插件全局的引入所要使用的js庫
new webpack.ProvidePlugin({ $:"jquery" })
],
// 這款插件用於壓縮 JS 代碼,減小資源體積大小
devServer: {
//設置基本目錄結構
contentBase: "./dist",//本地服務器所加載的頁面所在的目錄 || contentBase:path:path.resolve(__dirname,'dist')
//服務器的IP地址,可使用IP也可使用localhost
host:'localhost',
//服務端壓縮是否開啓
compress:true,
//配置服務端口號
port:5200,
historyApiFallback: true,//不跳轉
inline: true//實時刷新
}
};
複製代碼
pake.josn
{
"name": "md",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dv": "webpack --mode development",
"bd": "webpack --mode production",
"server": "webpack-dev-server --open"
},
"author": "",
"license": "ISC",
"dependencies": {
"html-withimg-loader": "^0.1.16",
"jquery": "^3.3.1",
"npm": "^6.0.1",
"to": "^0.2.9",
"update": "^0.7.4"
},
"devDependencies": {
"autoprefixer": "^8.5.0",
"babel-core": "^6.26.3",
"babel-loader": "^7.1.4",
"babel-preset-env": "^1.7.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"css-loader": "^0.28.11",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"file-loader": "^1.1.11",
"html-webpack-plugin": "^3.2.0",
"less": "^3.0.4",
"less-loader": "^4.1.0",
"postcss-loader": "^2.1.5",
"purify-css": "^1.2.5",
"purifycss-webpack": "^0.7.0",
"style-loader": "^0.21.0",
"uglifyjs-webpack-plugin": "^1.2.5",
"url-loader": "^1.0.1",
"webpack": "^4.8.3",
"webpack-cli": "^2.1.3",
"webpack-dev-server": "^3.1.4"
}
}
複製代碼