webpack从0-1打包运行项目
官方文档:Concepts | webpack
目录
一、webpack的基本使用
建立初始文件
二、自动生成html-webpack-plugin插件
三、webpack中处理css文件
四、分离css文件
五、webpack中处理less文件
六、webpack配置图片的加载 (webpack5已弃用,图片直接使用即可加载,无序再进行如下操作。下面的操作针对webpack4)
七、webpack配置清除dist目录的插件
八、webpack使用babel处理高版本的js语法(import、export等es6语法)
九、webpack-dev-server自动刷新
十、生产环境和开发环境
十一、webpack多入口的配置:多入口多出口
十二、webpack多入口-提取公共模块
十三、webpack处理vue
十四、webpack中路由的配置说明
十五、vue-cli脚手架环境搭建
十六、rem布局-插件postcss-pxtorem的配置
十七、vue-cli配置代理服务器
一、webpack的基本使用
-
建立初始文件
1、建立一个文件夹demo,用来放我们的项目
2、将新建的文件夹拖入到vscode
3、文件夹下新建目录文件夹dist,用来放我们打包之后的资源
4、文件夹下新建目录文件夹src/main.js,src源代码的位置
5、打开命令行
yarn init -y
6、安装依赖包(-D将依赖记录成开发依赖,只是开发中需要用的依赖,实际上线不需要的)
yarn add webpack webpack-cli -D
7、到package.json文件中,配置scripts
"scripts": {
"build":"webpack --config webpack.config.js"
}
8、新建webpack.config.js文件
const path = require("path");
//配置webpack的配置文件,需要将配置的对象导出,给webpack使用
module.exports = {
// 1. 入口 entry,从哪个文件开始打包
entry: "./src/main.js",
// 2. 出口 output,打包到哪里去
output: {
//打包输出的目录(输出的目录必须是一个绝对路径)
path: path.join(__dirname, "dist"),
//打包后生成的文件名
filename: "bundle.js",
},
// 3. 模式 mode development未压缩的,production压缩的。平常上线的是用production,但是因为我们现在想要看打包之后的内容,所以暂时先用development
mode: "development",
};
9、执行配置的scripts脚本
yarn build
打包成功
可以看到我们的dist文件夹下,新增了一个bundle.js文件,同时文件内也可以看到我们在main.js中的内容
二、自动生成html-webpack-plugin插件
1、新建一个文件夹:public,放一些不需额外处理,直接原封不动放入打包中的资源,例如html,网站logo等
此处,我暂时先新建一个index.html
2、下载(-D将依赖记录成开发依赖,只是开发中需要用的依赖,实际上线不需要的)
yarn add html-webpack-plugin -D
3、在webpack.config.js文件中,引入这个模块:
//引入自动生成html的插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
4、配置
plugins:[
new HtmlWebpackPlugin({ template:'./public/index.html' })
]
配置好之后,执行yarn build可以查看到dist文件夹下面多了一个index.html,并且这个Html内引用了我们的打包js文件
三、webpack中处理css文件
参考官方文档中:
1、在src下新建文件夹css,然后新建文件base.css
2、安装依赖
yarn add style-loader css-loader -D
3、 修改webpack.config.js文件
const path = require("path");
//引入自动生成html的插件
const HtmlWebpackPlugin = require("html-webpack-plugin");
//配置webpack的配置文件,需要将配置的对象导出,给webpack使用
module.exports = {
// 1. 入口 entry,从哪个文件开始打包
entry: "./src/main.js",
// 2. 出口 output,打包到哪里去
output: {
//打包输出的目录(输出的目录必须是一个绝对路径)
path: path.join(__dirname, "dist"),
//打包后生成的文件名
filename: "bundle.js",
},
// 3. 模式 mode development未压缩的,production压缩的。平常上线的是用production,但是因为我们现在想要看打包之后的内容,所以暂时先用development
mode: "development",
//4.配置模块加载规则
//默认,webpack只认识,json,javascript,不认识其他文件,如果希望打包处理其他文件,需要配置lodar
module: {
rules: [
{
//正则:匹配所有以css结尾的文件
test: /\.css$/,
//实际处理顺序:从右往左,先处理css-loader,再处理style-loader
//css-loader 让webpack能够识别解析css文件
//style-loader 通过动态的创建style标签的方式,让解析后的css内容,能够到页面中
use: ["style-loader", "css-loader"],
},
],
},
//5.配置插件,一般放最后
plugins: [new HtmlWebpackPlugin({ template: "./public/index.html" })],
};
4、在main.js中引入css文件
//导入css
require("./css/base.css");
console.log("======main.js打包测试");
5、 配置好之后,执行yarn build,可以查看到dist文件夹下bundle.js内引用了我们的css文件。并且dist文件夹下index.html浏览审查元素,可以看到css生效。
四、分离css文件
1、css文件夹下再新建一个index.css文件
2、main.js中引入上面新建的index.css文件
//导入css
require("./css/base.css");
require("./css/index.css");
console.log("======main.js打包测试");
3、执行yarn build,将dist文件夹下面的index.html拖入到浏览器
两个样式文件都起了作用,但是有两个<style></style>标签。若css样式多,创建的style也多,目前是通过js动态创建的css。
将css放到了style标签中,请求次数是少了,
但是如果css文件太大的话,也不是太好,所以必须将css分离出来
- 插件min-css-extract-plugin,这个插件支持webpack4.x
- 之前的插件extract-text-webpack-plugin对webpack3.x的版本支持(目前已废弃)
4、安装依赖包
yarn add mini-css-extract-plugin -D
5、在webpack.config.js文件中,引入这个模块
// 引入分离css文件的模块
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
6、配置loaders
将截图中的替换成如下:
module: {
rules: [
{
//正则:匹配所有以css结尾的文件
test: /\.css$/,
//实际处理顺序:从右往左,先处理css-loader,再处理style-loader
//css-loader 让webpack能够识别解析css文件
//style-loader 通过动态的创建style标签的方式,让解析后的css内容,能够到页面中
use: [ // 根据官方文档写的,注意'css-loader'的书写位置
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath:'../',
},
},
"css-loader"
],
},
],
},
7、插件的配置
plugins: [
...
//定义打包好的文件的存放路径和文件名
new MiniCssExtractPlugin({
filename:'css/index.css'
})
],
8、yarn build 之后,dist文件夹下面新增了css文件夹,css文件夹下新增了index.css文件
打开index.css文件,发现这个css文件内容为之前src/css下面的base.css和index.css两个文件全部的内容
然后在浏览器审查元素,发现不再是通过<style>标签引入,而是通过link标签引入
五、webpack中处理less文件
1、src文件夹下再新建一个less文件夹,less文件夹下新建一个header.less文件
2、打开public/index.html
增加<div class="header"></div>
3、打开main.js,导入less
4、下载依赖包(解析less文件需要识别less语法,所以除了less-loader需要额外下载less包)
yarn add less less-loader -D
5、打开webpack.config.js进行配置
//方法一:简单的以style标签放置解析的less
{
test: /\.less$/,
use:['style-loader','css-loader','less-loader']
}
//方法二:分离出css内容,以link引入less。两个方法不同时使用
{
test: /\.less$/,
use:[
//分离出css内容
{
loader:MiniCssExtractPlugin.loader,
options:{
publicPath:'../',
},
},
'css-loader',
'less-loader'
]
}
方法二比较好,会将我们的所有less文件和所有的css文件内的样式,统一封装到dist/css/index.css文件内
执行yarn build
六、webpack配置图片的加载 (webpack5已弃用,图片直接使用即可加载,无序再进行如下操作。下面的操作针对webpack4)
- webpack4
1、src文件夹下再新建一个imgs文件夹,文件夹下放入两张大小不一样的图片
2、修改header.less(若是webpack5,设置了背景图片之后,直接yarn build会发现,图片都已打包到dist目录下)
.header {
width: 100%;
height: 200px;
// background-color: pink;
background: url(../imgs/01.jpg);
}
3、此时需要转换图片的loader,来处理图片的问题,主要用到url-loader和file-loader
注意:url-loader中的部分功能要用到file-loader
下载依赖包
yarn add url-loader file-loader -D
4、 配置loader
图片默认转成base64字符串:审查元素能够看到路径是base64格式
好处就是浏览器不用发请求了,直接可以读取
坏处就是如果图片太大,再转base64就会让图片的体积增大30%左右。所以需要通过options配置选项进行配置limit,可以设置一个临界值,大于这个值会整个文件直接打包到目录中(dist打包文件夹下方会多出一张图片),得到是路径,如果小于这个值,就会转成base64,节约请求的次数
//(3)配置图片文件的解析,i 表示忽视大小写
{
test: /\.(png|jpg|gif)$/i,
use: [
//url-loader如果不配置,默认都会将文件转成base64字符串的格式
{
loader: "url-loader",
options: {
limit: 8 * 1024,
},
},
],
},
5、 webpack配置图片的输出目录
{
test: /\.(png|jpg|gif)$/i,
use: [
//url-loader如果不配置,默认都会将文件转成base64字符串的格式
{
loader: "url-loader",
options: {
// 超过8k就不转base64,小于8k才转字符串
limit: 8 * 1024,
// 配置输出的文件名
name:'[name].[ext]',
// 配置静态资源的引用路径
publicPath:'../images/',
//配置输出的文件目录
outputPath:'images/'
},
},
],
},
6、bundle.js配置文件的输出目录
output: {
//打包输出的目录(输出的目录必须是一个绝对路径)
path: path.join(__dirname, "dist"),
//打包后生成的文件名
filename: "js/bundle.js",
},
执行yarn build之后,dist下方多一个js文件夹包裹着bundle.js文件。webpack5也是同样的
- webpack5
1、src文件夹下再新建一个imgs文件夹,文件夹下放入两张大小不一样的图片(具体参考上面)
2、修改header.less,直接yarn build,图片都已打包到dist目录下
.header {
width: 100%;
height: 200px;
// background-color: pink;
background: url("../imgs/01.jpg");
}
3、配置loader
图片默认打包到目录中(dist打包文件夹下方会多出一张图片)
{
// 处理图片资源
test: /\.(jpg|png|gif)$/i,
// webpack5中使用assets-module(url-loader已废弃)
type: 'asset',
// 超过8k就不转base64,小于8k才转字符串
parser: {
dataUrlCondition: {
maxSize: 8 * 1024
}
},
generator: {
// 配置输出的文件名,name为原图片的名字,ext为原图片的后缀名。前面加上images/,那么dist目录下会新建一个文件夹images来放置打包后的图片
filename: 'images/[name][ext]'
}
},
4、执行yarn build之后,dist下方多一个images文件夹包裹着图片
七、webpack配置清除dist目录的插件
1、使用clean-webpack-plugin插件在每次打包前清除下dist文件夹
安装依赖包
yarn add clean-webpack-plugin -D
2、webpack.config.js
// 导入清除插件,可以在每次打包之前,清除dist目录的内容
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
//配置webpack的配置文件,需要将配置的对象导出,给webpack使用
module.exports = {
...
module: {
...
},
//5.配置插件,一般放最后
plugins: [
...
//调用清除打包目录插件
new CleanWebpackPlugin()
],
};
3、执行yarn build即可
八、webpack使用babel处理高版本的js语法(import、export等es6语法)
babel的介绍=》用于处理高版本js语法的兼容性
1、修改src/main.js
//箭头函数在低版本内不会被识别
const fn = () =>{
console.log('嘎嘎')
}
2、yarn build之后,查看dist/js/bundle.js内查看对应的函数,发现还是箭头函数,没有被解析
3、安装包
yarn add -D babel-loader @babel/core @babel/preset-env
4、修改webpack.config.js ( module: { rules: [内放置如下代码] } )
//(4)配置对于高版本js的兼容性处理
{
//匹配js
test:/\.js$/,
//排除node_modules
exclude: /(node_modules)/,
use:{
loader:'babel-loader',
options:{
presets:['@babel/preset-env']
}
}
}
5、yarn build之后,查看dist/js/bundle.js内查看对应的函数,被解析了
箭头函数变成了普通函数,处理了兼容性
九、webpack-dev-server自动刷新
1、下载
yarn add webpack-dev-server -D
2、修改package.json文件
"scripts": {
"build": "webpack --config webpack.config.js",
"dev": "webpack-dev-server --config webpack.config.js"
}
3、执行yarn dev (yarn build上线的时候执行一次即可,其他时间建议yarn dev)
执行后显示一个链接,点开可以看到我们当前页面,而且每次修改保存之后,都会自动刷新
4、webpack-dev-server的配置
module.exports={
...
//配置开发服务器
devServer:{
port:3000,//配置端口号3000
open:true//自动打开浏览器
}
}
5、 执行yarn dev
自动打开 http://localhost:3000/页面,而且也有保存刷新的作用。
十、生产环境和开发环境
生产环境和开发环境刚好相反,开发环境在本地运行,而生产环境是要产出运行在服务器给用户使用的代码,因此两者的构建目标差异很大,比如打包后的文件在生产环境中要尽可能的小,逻辑代码分离,优化静态资源(压缩图片)等。
因此开发环境和生产环境不能共用一份webpack配置文件,需要分别指定
但是两个环境还是有很多配置可以共用的,比如entry、output、module等,因此可以把公共部分的配置抽离出来放到一个独立的文件然后进行合并,我们可以使用webpack-merge工具进行合并。
注意:entry、output、module这些配置在我们当前示例通用,但未必适合所有项目。
1、安装依赖
yarn add webpack-merge -D
2、拆分webpack.config.js文件,拆分后这个文件就不要了。
新建config文件夹,新建三个文件webpack.base.js、webpack.pro.js、webpack.dev.js
- webpack-demo
- config // 存放配置文件的文件夹
- webpack.base.js // 公共的配置
- webpack.dev.js // 开发环境的配置
- webpack.pro.js // 生产环境的配置
3、webpack.base.js(
注意:更改绝对路径:path: path.join(__dirname, "../dist"),
相对目录的路径不用更改,因为在运行时还是以整个项目根目录运行
)
将之前的webpack.config.js 文件内,公用部分粘贴过来
// 公共的一些配置
const path = require("path");
//引入自动生成html的插件
const HtmlWebpackPlugin = require("html-webpack-plugin");
// 引入分离css文件的模块
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 导入清除插件,可以在每次打包之前,清除dist目录的内容
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
// 配置webpack的配置文件,需要将配置的对象导出,给webpack使用
module.exports = {
// 入口 entry,从哪个文件开始打包
entry: "./src/main.js",
// 出口 output,打包到哪里去
output: {
// 打包输出的目录(输出的目录必须是一个绝对路径)
path: path.join(__dirname, "../dist"),
// 打包后生成的文件名
filename: "js/bundle.js",
},
// 配置模块加载规则
// 默认,webpack只认识,json,javascript,不认识其他文件,如果希望打包处理其他文件,需要配置lodar
module: {
rules: [
{
// 正则:匹配所有以css结尾的文件
test: /\.css$/,
// 实际处理顺序:从右往左,先处理css-loader,再处理style-loader
// css-loader 让webpack能够识别解析css文件
// style-loader 通过动态的创建style标签的方式,让解析后的css内容,能够到页面中
use: [ // 根据官方文档写的,注意'css-loader'的书写位置
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath:'../',
},
},
"css-loader"
],
},
// 配置less文件的解析
// 方法一:简单的以style标签放置解析的less
// {
// test: /\.less$/,
// use:['style-loader','css-loader','less-loader']
// }
// 方法二:分离出css内容,以link引入less。两个方法不同时使用
{
test: /\.less$/,
use:[
// 分离出css内容
{
loader:MiniCssExtractPlugin.loader,
options:{
publicPath:'../',
},
},
'css-loader',
'less-loader'
]
},
// (3)配置图片文件的解析,i 表示忽视大小写,webpack4
// {
// test: /\.(png|jpg|gif)$/i,
// use: [
// //url-loader如果不配置,默认都会将文件转成base64字符串的格式
// {
// loader: "url-loader",
// options: {
// // 超过8k就不转base64,小于8k才转字符串
// limit: 8 * 1024,
// // 配置输出的文件名
// name:'[name].[ext]',
// // 配置静态资源的引用路径
// publicPath:'../images/',
// //配置输出的文件目录
// outputPath:'images/'
// },
// type: 'javascript/auto', //在webpack5中使用旧版功能
// },
// ],
// },
{
// 处理图片资源:webpack5
test: /\.(jpg|png|gif)$/i,
// webpack5中使用assets-module(url-loader已废弃)
type: 'asset',
// 超过8k就不转base64,小于8k才转字符串
parser: {
dataUrlCondition: {
maxSize: 8 * 1024
}
},
generator: {
// 配置输出的文件名,name为原图片的名字,ext为原图片的后缀名。前面加上images/,那么dist目录下会新建一个文件夹images来放置打包后的图片
filename: 'images/[name][ext]'
}
},
// (4)配置对于高版本js的兼容性处理
{
// 匹配js
test:/\.js$/,
// 排除node_modules
exclude: /(node_modules)/,
use:{
loader:'babel-loader',
options:{
presets:['@babel/preset-env']
}
}
}
],
},
// 配置插件,一般放最后
plugins: [
new HtmlWebpackPlugin({ template: "./public/index.html" }),
// 定义打包好的文件的存放路径和文件名
new MiniCssExtractPlugin({
filename:'css/index.css'
}),
// 调用清除打包目录插件
new CleanWebpackPlugin()
],
};
4、webpack.pro.js
src内才可任意使用import和export。src外还是得使用require
// production 生产环境
// 导入公共的配置
const base = require('./webpack.base.js')
// 导入一个用于合并的包
const webpackMerge = require('webpack-merge')
// 导出生产环境的配置
// merge可以传入多个参数,会将多个参数合并成一个对象
// 如果有重复的属性名,后面的对象属性会覆盖前面的
module.exports = webpackMerge.merge(base, {
// 模式 mode development未压缩的,production压缩的。平常上线的是用production,但是因为我们现在想要看打包之后的内容,所以暂时先用development
mode: "production"
})
5、webpack.dev.js
// development 开发环境的配置
// 导入公共的配置
const base = require('./webpack.base.js')
// 导入一个用于合并的包
const webpackMerge = require('webpack-merge')
// 导出开发环境的配置
// merge可以传入多个参数,会将多个参数合并成一个对象
// 如果有重复的属性名,后面的对象属性会覆盖前面的
module.exports = webpackMerge.merge(base, {
// 模式 mode development未压缩的,production压缩的。平常上线的是用production,但是因为我们现在想要看打包之后的内容,所以暂时先用development
mode: "development",
//配置开发服务器
devServer: {
port:3000,//配置端口号3000
open:true//自动打开浏览器
}
})
如上三个代码完成之后,删除之前的webpack.config.js
6、修改package.json文件
"scripts": {
"build": "webpack --config config/webpack.pro.js",
"dev": "webpack-dev-server --config config/webpack.dev.js"
}
7、执行yarn build和yarn dev即可
十一、webpack多入口的配置:多入口多出口
多入口需要修改entry配置,在这之前我们都是把src/main.js打包成dist/bundle.js引入到项目中,那如果有多个main.js类型的文件需要引入时,就需要配置多入口
在src下新建两个文件index.js 和about.js
1、index.js
const app = document.querySelector('#app')
const h1 = document.createElement('h1')
h1.innerHTML = '大家好,我是index.js'
app.appendChild(h1)
2、about.js
const app = document.querySelector('#app')
const h2 = document.createElement('h2')
h2.innerHTML = '大家好,我是about.js'
app.appendChild(h2)
3、 然后修改config/webpack.base.js
entry: {
index:'./src/index.js',
about:'./src/about.js',
},
// 出口 output,打包到哪里去
output: {
// 打包输出的目录(输出的目录必须是一个绝对路径)
path: path.join(__dirname, "../dist"),
// 打包后生成的文件名
// filename: "js/bundle.js",
filename: "js/[name].bundle.js", //[name]指代entry中的键名
},
4、 yarn build
dist/js下面出现两个js文件
打开dist/index.html可以看到两个js文件生效了
十二、webpack多入口-提取公共模块
1、安装依赖
yarn add jquery
2、修改index.js和about.js,给他们都加上如下代码
src目录内所以可以使用import,没必要还用require
import $ from 'jquery'
console.log($('div'))
3、执行yarn build
查看打包后的index.bundle.js和about.bundle.js文件源码,会发现他们都把jquery.js打包进去了,这样做的后果不敢想象。所以我们需要把类似公共的依赖模块提取到一个单独的文件中。
4、修改config/webpack.base.js
//其他代码
module.exports = {
// 其他代码
// + 提取公共模块配置
optimization: {
splitChunks: {
chunks: 'all' // 提取所有文件的共同模块
}
}
}
5、再次执行yarn build
可以看到当前项目的公共模块jquery的内容已经被打包到一个独立的....bundle.js文件中了,当然这个文件名可以通过配置修改的。
6、更改公共模块打包后的文件名
//其他代码
module.exports = {
// 其他代码
// + 提取公共模块配置
optimization: {
cacheGroups: {
defaultVendors: {
filename: 'js/common.bundle.js',
},
},
splitChunks: {
chunks: 'all' // 提取所有文件的共同模块
}
}
}
执行yarn build
注意:公共模块的大小必须大鱼 30kb 才会被独立打包,jquery的大小是87kb
十三、webpack处理vue
1、安装vue
yarn add vue
2、记得安装插件
3、 src下新建App.vue
// 使用App组件,渲染index.html中的视图
import Vue from 'vue'
import App from './App.vue'
new Vue({
el:'#app',
// 使用vue底层的渲染方法
// 作用:使用App组件,作为根组件,将来渲染视图
// 简写:render:h=>h(App)
// 完整写
render:function(createElement){
return createElement(App)
}
})
4、src/ main.js文件
// 使用App组件,渲染index.html中的视图
import Vue from 'vue'
new Vue({
el:'#app',
// 使用vue底层的渲染方法
// 作用:使用App组件,作为根组件,将来渲染视图
// 简写:render:h=>h(App)
// 完整写
render:function(createElement){
return createElement(App)
}
})
5、安装依赖包
yarn add vue-loader vue-template-compiler -D
6、修改webpack.base.js文件
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
module:{
rules: [
//...其他规则
{
test: /\.vue$/,
loader:'vue-loader'
}
]
},
plugins:[
//请确保引入这个插件!
new VueLoaderPlugin()
]
}
webpack.base.js文件完整代码(包含之前的其他操作,此处先用单入口,单出口)
// 公共的一些配置
const path = require("path");
//引入自动生成html的插件
const HtmlWebpackPlugin = require("html-webpack-plugin");
// 引入分离css文件的模块
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 导入清除插件,可以在每次打包之前,清除dist目录的内容
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin')
// 配置webpack的配置文件,需要将配置的对象导出,给webpack使用
module.exports = {
// 入口 entry,从哪个文件开始打包
entry: "./src/main.js",
// entry: {
// index:'./src/index.js',
// about:'./src/about.js',
// },
// 出口 output,打包到哪里去
output: {
// 打包输出的目录(输出的目录必须是一个绝对路径)
path: path.join(__dirname, "../dist"),
// 打包后生成的文件名
filename: "js/bundle.js",
// filename: "js/[name].bundle.js", //[name]指代entry中的键名
},
// 配置模块加载规则
// 默认,webpack只认识,json,javascript,不认识其他文件,如果希望打包处理其他文件,需要配置lodar
module: {
rules: [
{
// 正则:匹配所有以css结尾的文件
test: /\.css$/,
// 实际处理顺序:从右往左,先处理css-loader,再处理style-loader
// css-loader 让webpack能够识别解析css文件
// style-loader 通过动态的创建style标签的方式,让解析后的css内容,能够到页面中
use: [ // 根据官方文档写的,注意'css-loader'的书写位置
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath:'../',
},
},
"css-loader"
],
},
// 配置less文件的解析
// 方法一:简单的以style标签放置解析的less
// {
// test: /\.less$/,
// use:['style-loader','css-loader','less-loader']
// }
// 方法二:分离出css内容,以link引入less。两个方法不同时使用
{
test: /\.less$/,
use:[
// 分离出css内容
{
loader:MiniCssExtractPlugin.loader,
options:{
publicPath:'../',
},
},
'css-loader',
'less-loader'
]
},
// (3)配置图片文件的解析,i 表示忽视大小写,webpack4
// {
// test: /\.(png|jpg|gif)$/i,
// use: [
// //url-loader如果不配置,默认都会将文件转成base64字符串的格式
// {
// loader: "url-loader",
// options: {
// // 超过8k就不转base64,小于8k才转字符串
// limit: 8 * 1024,
// // 配置输出的文件名
// name:'[name].[ext]',
// // 配置静态资源的引用路径
// publicPath:'../images/',
// //配置输出的文件目录
// outputPath:'images/'
// },
// type: 'javascript/auto', //在webpack5中使用旧版功能
// },
// ],
// },
{
// 处理图片资源:webpack5
test: /\.(jpg|png|gif)$/i,
// webpack5中使用assets-module(url-loader已废弃)
type: 'asset',
// 超过8k就不转base64,小于8k才转字符串
parser: {
dataUrlCondition: {
maxSize: 8 * 1024
}
},
generator: {
// 配置输出的文件名,name为原图片的名字,ext为原图片的后缀名。前面加上images/,那么dist目录下会新建一个文件夹images来放置打包后的图片
filename: 'images/[name][ext]'
}
},
// (4)配置对于高版本js的兼容性处理
{
// 匹配js
test:/\.js$/,
// 排除node_modules
exclude: /(node_modules)/,
use:{
loader:'babel-loader',
options:{
presets:['@babel/preset-env']
}
}
},
{
test: /\.vue$/,
loader:'vue-loader'
}
],
},
// 配置插件,一般放最后
plugins: [
new HtmlWebpackPlugin({ template: "./public/index.html" }),
// 定义打包好的文件的存放路径和文件名
new MiniCssExtractPlugin({
filename:'css/index.css'
}),
// 调用清除打包目录插件
new CleanWebpackPlugin(),
new VueLoaderPlugin()
],
optimization: {
splitChunks: {
cacheGroups: {
defaultVendors: {
filename: 'js/common.bundle.js',
},
},
chunks: 'all' // 提取所有文件的共同模块
}
}
};
十四、webpack中路由的配置说明
大部分文件参考十三的文件
1、 src下新建App.vue
<template>
<div id="app">
我是vue页面
<!-- 路由出口 -->
<router-view></router-view>
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
2、 src下新建文件夹views,views文件夹下新建两个文件Home.vue和Login.vue
Home.vue
<template>
<div class="home">
这是home组件
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
Login.vue
<template>
<div class="home">
这是login组件
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
3、安装依赖包
yarn add vue-router
4、src下新建文件夹router,router文件夹下新建一个文件index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import Login from '../views/Login.vue'
Vue.use(VueRouter)
const router = new VueRouter({
routes:[
//redirect表示重定向
{path:'/',redirect:'/home'},
{path:'/home',component:Home},
{path:'/login',component:Login},
]
})
export default router
5、修改src下main.js,将上面的router文件挂载到实例上
import Vue from 'vue'
import App from './App.vue'
import router from './router'
new Vue({
el:'#app',
// 使用vue底层的渲染方法
// 作用:使用App组件,作为根组件,将来渲染视图
// 简写:render:h=>h(App)
// 完整写
render:function(createElement){
return createElement(App)
},
router
})
最简略的 main.js
// 使用App组件,渲染index.html中的视图
import Vue from 'vue'
import App from './App.vue'
import router from './router'
new Vue({
render:(h)=>h(App),
router
}).$mount('#app')
6、yarn dev即可看到默认访问到home组件,路由更换为login时,会跳转到Login组件。一个简短的路由搭建就完成了
十五、vue-cli脚手架环境搭建
借鉴此网站: 创建一个项目 | Vue CLI
1、命令行
vue create webpack-vue-mobile
2、 手动设置的一些步骤
空格是选中,回车是选择结束
代码风格,一般选择标准,不加分号
最后一个是否保存预设,一般不保存预设
3、项目新建成功后,对比上一步中,我们自己使用webpack搭建的vue项目
配置集成到node_modules文件夹内了,所以对比我们自己搭建的,会发现没有看到config文件夹
4、yarn serve启动项目,可以看出我们项目新建成功
5、覆盖vue脚手架自带的一些配置
src同级下新建vue.config.js文件,该文件内进行的配置会自动覆盖脚手架。
参考之前的配置即可。
//这里面配置的内容,会覆盖默认的webpack配置
module.exports = {
devServer: {
port:3001,//配置端口号3001
open:true//自动打开浏览器
}
}
十六、rem布局-插件postcss-pxtorem的配置
结合上面十五中创建的vue脚手架
参考网址: 基于vue-cli3的vue项目移动端样式适配,lib-flexible和postcss-px2rem - 秋风2016 - 博客园
1、安装插件
yarn add lib-flexible postcss-px2rem
2、在public中的index.html中删除meta标签
flexible会为页面根据屏幕自动添加<meta name='viewport'>标签,动态控制initial-scale,maximum-scale,minimum-scale等属性的值。
public中的index.html文件,与我们自己搭建的项目多了如下代码,但是可以直接删除,没啥作用
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
3、在src/main.js中导入插件包
// 导入rem的js,动态的设置了,不同屏幕的html根元素的font-size
// 1rem根据当前屏幕html font-size进行转换的
import 'lib-flexible'
4、配置vue.config.js
//这里面配置的内容,会覆盖默认的webpack配置
module.exports = {
devServer: {
port:3001,//配置端口号3001
open:true//自动打开浏览器
},
//rem的配置
css:{
loaderOptions:{
css:{},
postcss:{
plugins:[
require('postcss-px2rem')({
//适配 375 屏幕,设计图750中量出来的尺寸要 / 2
//配置成 37.5 是为了兼容 没有适配 rem 布局的第三方 ui 库
//若后期想适配 360 屏幕,remUnit:36
remUnit:37.5
})
]
}
}
}
}
5、为了效果更明显,我们删除项目内一些内容
(1)打开App.vue
删除样式和多余内容,仅保留<router-view/>
<template>
<div id="app">
<router-view/>
</div>
</template>
<style lang="less">
</style>
(2)删除components、assets两个文件夹
(3)修改router文件夹下index.js
import { createRouter, createWebHashHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'
const routes = [
{
path: '/',
redirect: '/home'
},
{
path: '/home',
component: Home
},
{
path: '/about',
component: About
},
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router
(4)修改views文件夹下Home.vue
<template>
<div class="home">这是home组件</div>
</template>
<script>
export default {
}
</script>
<style lang="less">
.home{
width: 200px;
height: 200px;
background-color: pink;
}
</style>
(5)修改views文件夹下About.vue
<template>
<div class="home">这是about组件</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
(6)yarn serve,然后审查元素
可以发现px都转成rem
十七、vue-cli配置代理服务器
跨域:域名 端口 协议 不同,就会跨域
比如:前端浏览器,运行代码,localhost:3000/... 请求后台服务器:localhost:8080/...
webpack的反向代理,可以起一个临时的代理服务器,帮助解决在开发过程中的跨域问题,就算跨域了也能拿到后台的数据
1、安装axios,发送ajax请求
yarn add axios
2、随便找一个别人的请求
比如打开别人的官网,审查network,选择Fetch/XHR,选择一个返回结果较少的get请求,复制链接
3、在我们十六中修改的Home.vue中发送请求
<template>
<div class="home">这是home组件</div>
</template>
<script>
import axios from 'axios'
export default {
async created () {
// 发送ajax请求,获取数据
// 此处原本复制的链接是:https://c.y.qq.com/splcloud/fcgi-bin/gethotkey.fcg?... 但是我们将 https://c.y.qq.com/splcloud/fcgi-bin 剪切到我们vue.config.js target中
// 此处链接因为将前面的部分剪切到vue.config.js target中,所以链接前面加上vue.config.js proxy设置的 /music/
const url = '/music/gethotkey.fcg?_=1637668473586&cv=4747474&ct=24&format=json&inCharset=utf-8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=1&uin=0&g_tk_new_20200303=63876982&g_tk=5381&hostUin=0'
const res = await axios.get(url)
console.log('=============res', res)
}
}
</script>
<style lang="less">
.home{
width: 200px;
height: 200px;
background-color: pink;
}
</style>
4、配置代理(配置vue.config.js文件)
//这里面配置的内容,会覆盖默认的webpack配置
module.exports = {
devServer: {
port:3001,//配置端口号3001
open:true,//自动打开浏览器
//配置代理服务器,进行代理数据
proxy:{
// 将来只要请求的路径,以 /music 开头,都会被代理
// /music/list =>https://c.y.qq.com/splcloud/fcgi-bin/list
'/music':{
target:'https://c.y.qq.com/splcloud/fcgi-bin/', //代理的基础路径
pathRewrite:{'^/music':''}
}
}
},
//rem的配置
css:{
loaderOptions:{
css:{},
postcss:{
plugins:[
require('postcss-px2rem')({
//适配 375 屏幕,设计图750中量出来的尺寸要 / 2
//配置成 37.5 是为了兼容 没有适配 rem 布局的第三方 ui 库
//若后期想适配 360 屏幕,remUnit:36
remUnit:37.5
})
]
}
}
}
}
5、重新yarn serve启动,即可在打印台看到数据请求成功
十八、
对我们的react项目进行webpack打包
- 通过npx create-react-app my-app生成项目my-app,并通过cd定位到该项目下
- cd到项目目录下,执行如下代码,这个是安装到系统下得,供往后可以以webpack命令打包
cd my-app
npm i webpack webpack-cli -g
报错:-bash: cnpm: command not found
安装cnpm
npm install cnpm -g --registry=https://registry.npm.taobao.org
报错
原因: 执行命令行命令时没有获得管理员权限
解决方案:在命令行前面添加sudo获取管理员权限,输入管理员密码就行
原因: 执行命令行命令时没有获得管理员权限
例如原来的是: npm install cnpm -g --registry=https://registry.npm.taobao.org
应该该为:sudo npm install cnpm -g --registry=https://registry.npm.taobao.org 再输入密码就行
- cd到项目目录下,直接安装即可,这个是安装到系统下得,供往后可以以webpack命令打包
cnpm i webpack webpack-cli -g
或者
sudo cnpm i webpack webpack-cli -g
- 这个是安装到项目依赖里面去,也就是在node_mudule里面
npm i --save-dev webpack webpack-dev-server webpack-cli
- 安装必要的依赖
npm i --save-dev babel-core babel-loader @babel/preset-env @babel/preset-react html-webpack-plugin
- package.json
检查package里面的devDependencies
调整package里面的scripts为如下代码
"scripts": {
"start": "webpack-dev-server --mode development --open --hot",
"buile": "webpack --mode production"
},
- webpack.config.js
根目录新建一个webpack.config.js文件,实例代码如下:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
//by https://blog.csdn.net/moshowgame
//当entry是个数组的时候,里面同样包含入口js文件,另外一个参数可以是用来配置webpack提供的一个静态资源服务器,webpack-dev-server。webpack-dev-server会监控项目中每一个文件的变化,实时的进行构建,并且自动刷新页面:
//当entry是个对象的时候,我们可以将不同的文件构建成不同的文件,按需使用,比如在我的hello页面中只要\引入hello.js即可:
entry: "./src/index.js",
//打包後生成的檔案路徑
output: {
path: path.join(__dirname, "dist"),
filename: "index_bundle.js",
},
//自动补全,后缀可以省略不写
//webpack在构建包的时候会按目录的进行文件的查找,resolve属性中的extensions数组中用于配置程序可以自行补全哪些文件后缀:
//onfiguration.resolve.extensions[0] should be an non-empty string.A non-empty string .请把[]中得''去掉
resolve: {
extensions: [".js", ".jsx", ".css", ".scss", ".json"],
alias: {
//配置后可以直接用@来表示这个位置,直接应用目录下得文件,是绝对路径
"@": path.join(__dirname, "./src"),
},
},
//設置 eval 或 SourceMap 屬性,debug 用
//devtool: 'cheap-module-eval-source-map',
module: {
rules: [
{
//自動編譯 JSX 或 JS 檔 (require 可載入 JSX 了)
test: /\.(js|jsx)$/,
use: { loader: "babel-loader" },
exclude: /node_modules/,
},
//, {
// //自動處理 CSS 內的 url 和 @import 的路徑轉換,可以傳入 sourceMap 參數以便 debug
// test: /\.css$/,
// loader: 'style!css?sourceMap'
// }, {
// //自動編譯 sass 檔成 CSS (require 可載入 sass 了),可以傳入 sourceMap 參數以便 debug
// test: /\.scss$/,
// loader: 'style!css?sourceMap!sass?sourceMap'
// }, {
// //自動編譯 less 檔成 CSS (require 可載入 less 了),可以傳入 sourceMap 參數以便 debug
// test: /\.less$/,
// loader: 'style!css?sourceMap!less?sourceMap'
// }, {
// //自動將圖片轉成 Data URL
// test: /\.(jpe?g|JPE?G|png|PNG|gif|GIF|svg|SVG|woff|woff2|eot|ttf)(\?v=\d+\.\d+\.\d+)?$/,
// loader: 'url?limit=1024&name=[sha512:hash:base64:7].[ext]'
// }
],
},
plugins: [
//https://github.com/jantimon/html-webpack-plugin
//This will generate a file dist/index.html and autp-import index_bundle.js
new HtmlWebpackPlugin({
filename: "index.html",
template: "src/index.html",
}),
],
};
- .babelrc
根目录新增一个.babelrc文件,输入以下内容
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}
- src目录
新增index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<p>welcome to react-world</p>
<div id="root"></div>
</body>
</html>
- npm start出现报错Error: Cannot find module 'webpack-cli/bin/config-yargs'
百度了一些解决办法
* 解决方法一:
安装webpack-cli即可:
cnpm i webpack-cli -D
(测试无效)
* 解决方法二:
卸载当前版本的webpack和webpack-dev-server:
cnpm uninstall webpack -g
cnpm uninstall webpack-dev-server -g
指定老版本安装:
cnpm i webpack@3.8.0 -D
cnpm i webpack-dev-server@2.9.7 -D
- 打包之后,用户看不到最新的,浏览器缓存
all-round: 感谢分享
郑建洋: 什么问题
ma3189524997: 重新运行一下就好了
西瓜不吃瓜: 为什么我的出不来效果呀
崽崽的谷雨: postcss-preser-env 这个库我怎么在npm 查不到啊?