注:此文中 webpack 使用的版本是 3.12.0,webpack-dev-server 2.11.5
npm install webpack -g --save
npm install [email protected] -D // @3.12.0指定安装的webpack版本
webpack.config.js 配置文件
const path = require("path");
module.exports = {
entry:'./src/app.js',// 入口 告诉webpack 项目的入口
output:{
path:path.resolve(__dirname,'dist'), // 第一个参数表示绝对路径,第二个参数表示指定的文件夹
filename:'main.js' // 指定编译打包后的文件名字
}
}
在 webpack-demo 文件夹下,新建文件夹 src,在 src 文件夹下创建项目入口文件 app.js
app.js中内容:
console.log("Hello Webpack!!!")
package.json 文件修改:
{
"name": "01",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"dev": "webpack"
},
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^3.12.0"
}
}
在 script 中指定运行的环境
"dev":"webpack" // 默认会找项目中的webpack.config.js 文件,打包是按照这个文件来进行的
"dev":""webpack --config webpack.config.dev.js" // 指定的运行文件是webpack.config.dev.js 可通过这里配置不同的运行环境(Dev uat prod)"
npm run dev
运行结果,在webpack-demo 文件夹下生成一个dist文件夹,里面生成一个main.js 的编译后的文件,内容如下:
至此,webpack 可以实现js 的基本编译打包效果,接下来将通过安装一些webpack plugin 来实现一些有意思的效果。
通过指定的 html 模板,指定生成的 html 文件名称,将在 dist 文件中指定位置生成一个插入指定 js 的打包后的 html 文件。
接下来,我们通过在 webpack 中配置 html-webpack-plugin
npm install [email protected] -D
webpack.config.js 中的配置如下:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
entry: './src/app.js', // 入口 告诉webpack 项目的入口
output: { // 生成新的js文件放在哪里
path: path.resolve(__dirname,'dist'),// 需要给个绝对路径
filename:"main.js"
},
plugins: [
new HtmlWebpackPlugin({
filename: 'aac.html',
template: 'src/index.html'
})
]
};
模板文件内容
执行 【npm run dev】 编译后在dist 文件夹下生成一个名为: aac.html 的文件
打开aac.html 在浏览器控制台输出如下内容:
loader 是webpack 用来预处理模块的,在一个模块被引入之前,会预先使用loader 处理模块的内容,下面介绍的是
npm i -S [email protected]
npm i -S [email protected]
npm i -D [email protected]
npm i -D [email protected]
npm i -D [email protected]
webpack.config.js 中配置如下:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
entry: './src/app.js', // 入口 告诉webpack 项目的入口
output: { // 生成新的js文件放在哪里
path: path.resolve(__dirname,'dist'),// 需要给个绝对路径
filename:"main.js"
},
plugins: [
new HtmlWebpackPlugin({
filename: 'aac.html',
template: 'src/index.html'
})
],
module:{
rules:[{
test: /\.js$/, // 匹配js文件
use:[{
loader:'babel-loader',
options:{
presets:['react'] // 需要安装 babel-preset-react
} // 配置babelloader 指定使用什么样的预设处理什么样的内容
}] // 使用什么loader处理
}]
}
};
修改 src 文件夹中的 app.js 文件内容如下:
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(
React
,
document.getElementById("root")
);
运行 【npm run dev】执行结果会在dist文件夹下生成 aac.html 文件和main.js,浏览器打开aac.html 展示的内容如下:
npm i -D [email protected]
package.json 中的配置更改
{
"name": "01",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack --config webpack.config.dev.js",
"start":"webpack-dev-server --config webpack.config.dev.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-preset-react": "^6.24.1",
"html-webpack-plugin": "^3.2.0",
"webpack": "^3.12.0",
"webpack-dev-server": "^2.11.5"
},
"dependencies": {
"react": "^15.6.2",
"react-dom": "^15.6.2"
}
}
执行 【npm run start 】运行的时候也进行了打包,打包后的资源放在了内存中,不会在项目中展示,当项目中内容更改保存之后,webpack-dev-server可以监视内容的变化,重新运行项目,内存中的资源被替换,且自动刷新浏览器.
webpack.config.js 中添加一下配置:
devServer: {
open:true, //自动打开浏览器
port:9000 // 指定端口号为 9000
}
npm i -D [email protected] // 编译css 的插件
npm i -D [email protected] // 会把打包的样式的内容插入到html结构中
webpack.config.js 的配置添加内容:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
entry: './src/app.js', // 入口 告诉webpack 项目的入口
output: { // 生成新的js文件放在哪里
path: path.resolve(__dirname,'dist'),// 需要给个绝对路径
filename:"main.js"
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'src/index.html'
})
],
module:{
rules:[
{
test: /\.js$/, // 匹配js文件
use:[
{
loader:'babel-loader',
options:{
presets:['react'] // 需要安装 babel-preset-react
} // 配置babelloader 指定使用什么样的预设处理什么样的内容
}
] // 使用什么loader处理
},{
test: /\.css$/, // 匹配 css文件 $ 表示结尾
use:['style-loader','css-loader']
}
]
},
devServer: {
open:true,
port:9000
}
};
注:webpack配置中的rules的执行规则是从右向左,从下向上。
npm i -D [email protected]
webpack.config.js在步骤10的基础上添加以下配置:
{
test: /\.(gif|png|jpe?g|svg)(\?.*)?$/,
use:['file-loader']
}
执行 npm run dev 之后打包的内容被放置在dist文件中,file-loader 把图片移植到了dist文件夹里面,并重新命名
CSS中引入背景图片如下:
//背景图片引入方式
body{
background: url("../img/1.jpeg");
}
img标签方式引入图片
import React from 'react';
import ReactDOM from 'react-dom';
import './common/style/main.css';
// 引入一张图片
import dog from "./common/img/1.jpeg"
// 得到一个图片名称 这个结果是file-loader处理的
console.log(dog) // ded8421faa9378eb5f948c1f92eada57.jpeg
ReactDOM.render(
,
document.getElementById("root")
);
npm - D [email protected]
url-loader 把图片转换为了base64 的编码格式
好处是:减少了图片的请求,只要进入页面就会加载对应的图片,当图片过大的时候编码量也会比较大。可设置当图片小到某个程度的时候就编码,大于某个程度就用图片
npm run dev 打包的时候不会单独把图片拷贝,而是以base64的形式打包进了js文件中
总结为小图片使用 base64的方式加载比较快,大图使用引入的方式
webpack.config.js 中的rules的配置添加以下内容:
{
test: /\.(gif|png|jpe?g|svg)(\?.*)?$/,
use:[
{
loader:'url-loader',
options:{
limit:1000000, // 以kb为单位 超过10kb就会被打包
}
}
]
}
在阿里巴巴矢量图库中创建自己项目,上传图标
下载文档,并在项目中创建fonts文件夹放入下载的文档内容,并在 iconfont.css 中添加以下代码:
@font-face {font-family: "iconfont";
src: url('iconfont.eot?t=1598601815966'); /* IE9 */
src: url('iconfont.eot?t=1598601815966#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAALsAAsAAAAABowAAAKgAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCCcAqBGIEsATYCJAMICwYABCAFhG0HLxvRBciemjyBYrLP4zEhsiYAuDvi4WmtvT87eyymSUS7aBPtnkgdWvYU6F7C/d9a++dSuTeYSbpzxGeXZfXNzeGSREvQapaJRAiNkJm8taXzRQ37gAMJIXs/7gINOKAXt58DrusBjDT+cczXJdBA8t3N55KRHAk4sOkAI5tsI/nkfxi7wCVsJ9BkUB7VbkdfEIwyq18gHjh2DIw5pyyzSCXUaqZmiCfQqdK++gXgMfx9/IOSMIKkLMDKOb5vn4Smr3I7RrP2Xxr0EeACAc0uUWAeyMR5bfCQRjCcRlNQaxTsKzP4Kv+v+2qxV4Vg/zorvQX0Q+Y9sVz2raYnkOPmJeBg1LNIvVv8/g6VNLjPIecqISILq38VzfNZlXY6Y/fhNtMGipKF1sVeSsV59idK1QeXcGCP7261iiqPFulYuFuMTa28o43aPeKFxEm+C7wRp9s3rJK2gXR2+V7NJt4EpmF9AEj4zzQB1GkuNQgCwfPWHxpx1DFatACfkomE9jot9DNTnckU/DFWz6qscyxVyiqr1pwsjeqb0KQJ9bC1y+9Yae/tRUOl9ybNDQZSKFTGkRk7D6Vm61BT2YAmczpnN+tGaEQ2AbO2AYQOt5C0+YBChy9kxv5Aqc8f1HSEBppchmfJZpPBmVsJHqN4Eo3PI25ClhhHQ81Rph+zCWGMZDkhPoxJnPOg4oKiYqQTS5jMMSI+w5ZQyiCGyCLqALthQZCRQuRpPEELpihVagoLmboPFUzIIpjtILAxFDYJGTcP4UyQSRi/MWUufd8PYyUIxpCWvBp1GEbEca0jxQoU9UB2CqVeefdyS9wMVgmKYiAMQiZCOkAnTCCQIUp9p2nYBKrA1Ai/okahXY/pKyxYXyx+QAYrwpKlsNtooLzi5jgJAA==') format('woff2'),
url('iconfont.woff?t=1598601815966') format('woff'),
url('iconfont.ttf?t=1598601815966') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('iconfont.svg?t=1598601815966#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.iconaixin:before {
content: "\e635";
}
app.js 中添加以下代码:
import React from 'react';
import ReactDOM from 'react-dom';
import './common/style/main.css';
import './common/fonts/iconfont.css';
ReactDOM.render(
,
document.getElementById("root")
);
webpack.config.js 中配置
字体图标模块的配置:
{
test: /\.(eot|ttf|woff|woff2|svg)?$/,
use:['file-loader']
}
模块化就是声明的css 类名会被重新编码(编译成一种新的方式)
比如 css :
body{
background: #888;
}
.ot{
background: #675;
}
app.js 代码:
import React from 'react';
import ReactDOM from 'react-dom';
import style from './common/style/main.css';
console.log(style) // {ot: "_1NA9HX7tOEtoQ9ESUKaGHL"}
import './common/fonts/iconfont.css';
ReactDOM.render(
React
,
document.getElementById("root")
如果ot 里面包含了一个ac,那么实现为:
import style from './common/style/main.css';
React
123
假设有两个css文件:
main.css中 ot 设置为灰色
aac.css中 ot 设置为蓝色
在使用的时候,两者相互独立互不影响
import React from 'react';
import ReactDOM from 'react-dom';
import style from './common/style/main.css';
console.log(style)
import aac from './common/style/aac.css';
import './common/fonts/iconfont.css';
ReactDOM.render(
React
123
,
document.getElementById("root")
效果:
更改webpack.config.js的配置为:
{
test: /\.css$/, // 匹配 css文件 $ 表示结尾
use:[
'style-loader',
{
loader:'css-loader',
options: {
modules:true,// false 不开启模块化
}
}
],
exclude: [ // 排除的文件夹不会被规则处理
// 1.当前文件夹下的 2.node_modules
path.resolve(__dirname,'node_modules'),
path.resolve(__dirname,'src/common')
]
},
{
test: /\.css$/,
use: ['style-loader','css-loader'], // 匹配规则是 从右向左匹配 从后往前
include: [
path.resolve(__dirname,'node_modules'),
path.resolve(__dirname,'src/common')
]
},
以上配置:
css
更改webpack.config.js 的配置
{
test: /\.css$/, // 匹配 css文件 $ 表示结尾
use:[
'style-loader',
{
loader:'css-loader',
// options: {
// modules:true,// false 不开启模块化
// }
options:{
modules:{
// localIdentName:'[hash:base64:6]',// 指定css的className名称,默认是 '[hash:base64]' :6 指定类名长度
// path: 当前文件所在目录 name: 文件名称 local: className名称
// localIdentName:'[path]-[name]-[local]-[hash:base64:6]',
localIdentName:'[name]-[local]_[hash:base64:6]',
}
}
}
],
exclude: [ // 排除的文件夹不会被规则处理
path.resolve(__dirname,'node_modules'), // 1.当前文件夹下的 2.node_modules
path.resolve(__dirname,'src/common')
]
},
npm i -D sass-loader@6
npm i -D node-sass@4
webpack配置中rules添加以下内容:
{
test: /\.scss$/,
use: [
'style-loader',
{
loader:'css-loader',
options:{
modules:{
localIdentName:'[name]-[local]_[hash:base64:6]',
}
}
},
'sass-loader'
]
},
app.js 中使用
import React from 'react';
import ReactDOM from 'react-dom';
import main from './common/style/main.scss'
ReactDOM.render(
React
,
document.getElementById("root")
执行结果:
注:less的配置和scss一样,安装对应的less-loader,添加配置和scss一样,只需要将匹配的文件后缀换为 test: /\.less$/
less 配置:
{
test: /\.less$/,
use:[
'style-loader',
{
loader:'css-loader',
options:{
modules:{
localIdentName:'[name]-[local]_[hash:base64:6]',
}
}
},
'less-loader'
],
exclude: [
path.resolve(__dirname,'node_modules'),
path.resolve(__dirname,'src/common')
]
},
{
test: /\.less$/,
use: ['style-loader','css-loader','less-loader'],
include: [
path.resolve(__dirname,'node_modules'),
path.resolve(__dirname,'src/common')
]
},
npm i -D babel-preset-env // env 这个预设用来处理es6 es7 等语法
webpack.config.js 配置
{
test: /\.js$/, // 匹配js文件
use:[
{
loader:'babel-loader',
options:{
presets:['react','env']
// react预设处理react语法
// env预设 处理es6 es7等语法
} // 配置babelloader 指定使用什么样的预设处理什么样的内容
}
] // 使用什么loader处理
},
以上配合不支持es6语法中的
let a = {a:1,b:2}
console.log({...a,c:3}) // 不支持
let c = Object.assign({},a,{c:3}) //支持
npm i -D babel-plugin-transform-object-rest-spread
比较早时期未规范的ES6语法的处理
webpack.config.js
{
test: /\.js$/, // 匹配js文件
use:[
{
loader:'babel-loader',
options:{
presets:['react','env'], // 需要安装 babel-preset-react react处理react语法 env 处理es6 es7等语法
plugins: ["transform-object-rest-spread"]
} // 配置babelloader 指定使用什么样的预设处理什么样的内容
}
] // 使用什么loader处理
},
let a = {a:1,b:2}
console.log({...a,c:3}) // 支持
let c = Object.assign({},a,{c:3}) //支持
.babelrc 文件是把babel-loader中配置的options内容配置放置进去
注意:.babelrc文件内容是json文件的格式所以都必须使用 " "
{
"presets":["react","env"],
"plugins": ["transform-object-rest-spread"]
}