网站首页 > 技术文章 正文
提示: 文中代码片段可能会在本文上传后格式被压缩,感兴趣的童鞋请复制代码到ide中格式化后查看,敬请谅解!
wenpack简介
- webpack是一个JavaScript应用的静态模块打包工具
- 前端模块化标准:AMD 、CMD 、 CommonJS 、 ES6
- 并且打包后将模块化的代码转换成浏览器能正常执行的代码
- 并且在通过模块化开发完成了项目后,还需要处理模块间的各种依赖,并且将其进行整合打包
- 而且不仅仅是JavaScript文件,开发中使用的Css,图片,json文件等等在webpack中可以被当作模块来使用
- 在打包过程中,还可以对资源进行处理,比如压缩图片,将scss,less转换成css,将ES6的语法转成ES5语法,将TypeScript转成JavaScript等操作
webpack安装
- 安装webpack首先需要安装Node.js,Node.js自带了软件包管理工具 npm
- 查看自己的node版本:命令:node -v
- 全局安装webpack(这里指定版本号3.6.0,因为vue vli2依赖此版本)命令: npm install webpack@3.6.0 -g (-g 表示全局安装)
- 局部安装webpack(后续才需要)命令: npm install webpack@3.6.0 --save-dev (--save-dev 是开发时依赖,项目打包后不需要继续使用的)
- 为什么全局安装后还需要局部安装在终端直接执行webpack命令,使用的是全局安装的webpack当在package.json中定义了scripts时,其中包含了webpack命令,那么使用的是局部的webpack
webpack的使用
基本打包命令
- 基本的打包命令 webpack 需要打包入口文件 打包后的文件路径 (webpack ./src/mian.js ./dist/bundle.js)在html中就直接引用这个打包后的js文件
webpack的配置
package.json 的配置
- 最好是自己手动创建一个该文件, 与src目录同层级
- 他也会在执行 npm init 命令后自动生成
- 一旦项目需要对node相关的包进行依赖的时候,首先对项目进行初始化 命令 npm init
- package.json文件结构如下
{
"name": "meetwebpack", //包名
"version": "1.0.0", //版本号
"description": "", //描述
"main": "index.js", //入口文件名
"scripts": { //脚本(命令映射)
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
"author": "", //作者
"license": "ISC", //开源协议
"devDependencies": { //开发时依赖的东西
"webpack": "^3.6.0"
},
"dependencies":{ //运行时依赖
},
}
- 如果package.json文件还依赖一些东西的话,这时候执行一下 npm install 命令,他会自动解决这些依赖
- 脚本(命令映射):
- 当执行 npm run build 命令的时候,相当于执行了 webpack 命令
- 当执行 npm run test 命令的时候 相当于执行了 echo "Error: no test specified" && exit 1 命令
- npm run 什么,就会去脚本中查找对应被映射的命令
- 为了开发中不出错,最好在项目目录本地安装 webpack,命令: npm install webpack@3.6.0 --save-dev
- 本地安装完成后,项目目录下会多出一个node_modules 文件夹
- 这样安装webpack就是开发时依赖,也就是说只有开发的时候才需要使用,真正运行上线的时候不需要这个
- package.json中的scripts的脚本在执行时,会按照一定的顺序寻找对应命令的位置
- 首先会寻找本地的node_modules/.bin路径中对应的命令
- 如果没有找到,会去全局的环境变量中寻找
webpack.config.js配置
- 手动创建一个该文件在src目录同层级
//导入path模块,用于动态获取出口文件夹的绝对路径
const path = require('path');
/*webpack配置文件应该导出一个对象*/
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
}
};
- entry:入口,要打包的入口文件路径
- output:出口对象
- path:打包后生成的文件路径,使用path.resolve(__dirname, '文件夹名字'), 这个函数会将node中的上下文和我们的文件夹名字进行拼接,形成最终打包文件存放的一个绝对路径
- filename:打包后的文件名
- 配置完成后直接执行命令 webpack 会自动对入口文件进行打包
loader
- 开发中不仅仅只有基本的js代码的处理,也需要加载css,图片,也包括一些高级的将ES6转成ES5代码,将less,sass转成css,将.jsx,.vue文件转换成js文件等等,对于webpack本身的功能来说,对于这些转化时不支持的,这时候就需要给webpack扩展对应的loader
- 开发中可以把css文件页当成模块,当入口文件mian.js对其有依赖的时候,webpack也会将其打包
//依赖其他js文件中的东西
import {flag, person} from './js/a.js';
console.log(flag);
console.log(person);
//依赖css,只需要依赖,不需要变量
require('./css/normal.css');
loader中文网站: https://www.webpackjs.com
步骤一:通过npm安装需要使用的loader
- 例如安装css的loader
npm install --save-dev css-loader
步骤二:在webpack.config.js中的module关键字下进行配置
const path = require('path');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.css$/,
use: ['css-loader' ]
}
]
}
};
- css - loader只负责加载,不负责解析,所以安装了css loader在打包后的网页时没有css效果的
- 这时候需要安装style loader
npm install style-loader --save-dev
- 安装完成之后需要与css loader结合使用
module: {
rules: [
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
}
]
}
- style-loader负责将样式添加到DOM中生效
- 使用多个loader时,webpack是从右往左读,先应用css-loader,再应用style-loader
less文件处理
- 如果在项目中使用less,sass,stylus来写样式,这里以less为例,其他也是一样
- 在入口js文件中依赖less
import {flag, person} from './js/a.js';
console.log(flag);
console.log(person);
//依赖CSS
require('./css/normal.css');
//依赖less
require('./css/special.less');
- 安装less-loader
npm install --save-dev less-loader less
- 配置less-loader
const path = require('path');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
},
{
test: /\.less$/,
use: [{
loader: "style-loader"
}, {
loader: "css-loader"
}, {
loader: "less-loader"
}]
}
]
}
};
webpack图片文件的处理
- 例如css代码中依赖了图片
body{
background: url("../img/2.jpg");
}
- 这时候打包会出错
- 需要安装处理图片的loader
npm install --save-dev url-loader
- 配置
const path = require('path');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.(png|jpg|gif|jpeg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
}
}
]
}
]
}
};
- limit:规定大小,单位:字节,当加载的图片小于limit时,会将图片编译成base64字符串形式,如果大于limit,它会使用file-loader来对图片进行加载,file-loader不需要特别的配置,只需要安装一下
npm install --save-dev file-loader
- 通过file-loader的方式加载图片的时候,他会把图片进行打包到dist文件夹中,形成一个新的文件,这时候原本代码中就读取不到这个新的图片文件了,这时候需要在webpack.config.js文件中的output中进行配置publicPath
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: 'dist/'
}
}
- 这样一来,在读取大小超过limit的图片时,他会自动的给使用图片路径的前面添加上publicPath的属性 + 打包后的文件应用到DOM中
- 这时候webpack会自动生成一个非常长的文件名字
- 这是一个32位的hash值,目的是防止文件名重复
- 但是真实开发中,可能会对打包的图片名有一定的要求,比如,将所有图片放在一个文件夹中,跟上图片原来的名称,同时也要防止重复 img/name.hash
- 在url-loader中的options里面还可以添加如下选项
- img:文件要打包到的文件夹
- name:获取图片原来的名字,放在该位置
- hash:8:为了防止图片片名称冲突,依然使用hash,但是我们只保留8位
- ext:使用图片原来的扩展名
{
test: /\.(png|jpg|gif|jpeg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 13000,
name: 'img/[name].[hash:8].[ext]'
}
}
]
}
- 其中的 name: 'img/[name].[hash:8].[ext]'
- img/:打包后生成的文件夹
- [name] : 这是一个变量,获取图片原来的名字
- [hash:8] : 防止文件名冲突,生成8位hash值
webpack ES6转ES5的babel
- 在webpack中,直接使用babel对应的loader就可以了
npm install --save-dev babel-loader@7 babel-core babel-preset-es2015
- 配置webpack.config.js文件
const path = require('path');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: 'dist/'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
}
]
}
};
webpack使用VUE的配置过程
- 在项目中使用VUE时,必须要对其有依赖,所以需要进行安装,因为在后续实际项目中也会使用vue, 所以并不是开发时依赖
- 安装vue
npm install vue --save
- 在项目中使用vue开发,对其进行依赖
import {flag, person} from './js/a.js';
console.log(flag);
console.log(person);
//依赖CSS
require('./css/normal.css');
//依赖less
require('./css/special.less');
//使用vue开发
import Vue from 'vue';
const app = new Vue({
el: '#app',
data:{
message: 'hellow vue'
}
});
- 修改完成后重新打包运行程序,打包时候并无报错,但是这时候在html中并不能使用vue相关的东西,因为vue在构建时一共两个版本:
- runtime-only:代码中,不能有任何的template,他会把挂载在el上的 #app当成一个template
- runtime-compiler:代码中可以有template,因为有compiler可以用于编译template
- 默认使用的runtime-only
- 解决办法,在webpack.config.js文件中的 module 后添加 resolve 配置
const path = require('path');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: 'dist/'
},
module: {
},
//添加下面的配置
resolve:{
alias:{
'vue#39;: 'vue/dist/vue.esm.js'
}
}
};
- 这时能正常使用vue相关内容
- html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>{{message}}</h2>
</div>
<script src="./dist/bundle.js"></script>
</body>
</html>
- js代码
import {flag, person} from './js/a.js';
console.log(flag);
console.log(person);
//依赖CSS
require('./css/normal.css');
//依赖less
require('./css/special.less');
//使用vue开发
import Vue from 'vue';
new Vue({
el: '#app',
data:{
message: 'hellow vue'
}
});
创建VUE时template和el关系
- 当前面的步骤正常运行之后:
- 如果我们希望将data中的数据显示在界面中,就必须修改 index.html
- 如果我们定义了组件,也必须修改 index.html来使用组件
- 但是html模板在开发中,并不希望手动的来频繁更改
定义template属性
- 在前面的Vue实例中,定义了el属性,用于index.html中的#app进行绑定,让Vue实例之后可以管理它其中的内容
- 这里,我们可以将div元素中的{{message}}内容更删除掉,只保留一个基本的id为div的元素
- 但是如果依然希望在其中显示 {{message}} 的内容,可以再定义一个template属性,代码如下:
const app = new Vue({
el: '#app',
template:`
<div>
<h2>{{message}}</h2>
</div>
`,
data:{
message: 'hellow vue',
},
methods:{
}
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
</div>
<script src="./dist/bundle.js"></script>
</body>
</html>
直接使用.vue文件进行开发
- 配置对应的loader
npm install vue-loader vue-template-compiler --save-dev
- 修改webpack.config.js配置文件
const path = require('path');
//导入这个模块
const VueLoaderPlugin = require('vue-loader/lib/plugin');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: 'dist/'
},
//添加这个配置
plugins: [
// make sure to include the plugin for the magic
new VueLoaderPlugin()
],
module: {
rules: [
{
test: /\.vue$/,
use: ['vue-loader']
}
]
},
resolve:{
alias:{
'vue#39;: 'vue/dist/vue.esm.js'
}
}
};
- vue-loader@15.*之后 必须配置带有VueLoaderPlugin 之外,还需另外单独配置css-loader。如果是用最新webpack原生构建,除了安装webpack外,还要安装webpck-cli,在webpack.config中配置mode选项
webpack横幅plugin的使用
- plugin和loader的区别
- plugin主要用于转换某些类型的模块,它是一个转换器
- plugin是插件,它是对webpack本身的扩展,是一个扩展器
- plugin使用过程
- 通过npm安装需要使用的plugins(某些webpack已经内置的插件不需要安装)
- 在webpack.config.js中的plugins中配置插件
- 以BannerPlugin 插件为例:
const path = require('path');
//1.导入对应的包
const webpack = require('webpack');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: 'dist/'
},
plugins: [
//2.使用插件
new webpack.BannerPlugin("最终版权归Xiao YouXin所有")
],
module: {
rules: [
{
test: /\.vue$/,
use: ['vue-loader']
}
]
},
resolve:{
extensions:['.js','.css','.vue'], //配置省略的扩展名
alias:{
'vue#39;: 'vue/dist/vue.esm.js'
}
}
};
- 在webpack.config.js中配置插件后重新打包代码,再看 dist文件夹中打包后的bundle.js文件会发现文件第一行出现了注释: 最终版权归Xiao YouXin所有
- webpack-HtmlWebpackPlugin的使用
- 之前的开发,index.html文件是放在项目根目录下的
- 在真实发布项目的时候,发布的是dist文件夹中的内容,但是dist文件夹中如果没有index.html文件,那么打包的js等文件也没有意义了
- 所以,我们需要将index.html文件打包到dist文件夹中,这个时候可以使用HtmlWebpackPlugin插件
- 它可以自动生成一个index.html文件(可以通过指定模板来生成)
- 将打包的js文件,自动通过script标签插入到body中
- 安装HtmlWebpackPlugin插件
npm install html-webpack-plugin --save-dev
- 使用插件,修改webpack.config.js文件中的plugins部分内容如下
- 这里的template表示根据什么模板来生成index.html
- 另外,需要删除在之前output中添加的publicPath属性
- 否则插入的script标签src可能会有问题
const path = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const webpack = require('webpack');
//1.引入安装插件的模块
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
//2.删除output下publicPath属性
},
plugins: [
new VueLoaderPlugin(),
new webpack.BannerPlugin("最终版权归Xiao YouXin所有"),
//3.使用插件
new HtmlWebpackPlugin({
//4.指定生成index.html模板
template: 'index.html'
})
],
module: {
rules: [
{
test: /\.vue$/,
use: ['vue-loader']
}
]
},
resolve:{
extensions:['.js','.css','.vue'], //配置省略的扩展名
alias:{
'vue#39;: 'vue/dist/vue.esm.js'
}
}
};
- webpack-UglifyjsWebpackPlugin的使用
- 在项目发布之前,需要对js等文件进行压缩处理
- 使用一个第三方插件ugilifyjs-webpack-liugin,并且指定版本号1.1.1,与CLI2保持一致
npm install uglifyjs-webpack-plugin@1.1.1 --save-dev
- 修改webpack.config.js文件,使用插件
const path = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const Webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
//1.引入插件模块
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
plugins: [
new VueLoaderPlugin(),
new Webpack.BannerPlugin("最终版权归Xiao YouXin所有"),
new HtmlWebpackPlugin({
template: 'index.html'
}),
//2.使用插件
new UglifyjsWebpackPlugin()
],
module: {
rules: [
{
test: /\.vue$/,
use: ['vue-loader']
}
]
},
resolve:{
extensions:['.js','.css','.vue'], //配置省略的扩展名
alias:{
'vue#39;: 'vue/dist/vue.esm.js'
}
}
};
- 这时候重新打包代码后,查看bundle.js文件就会发现这个文件中的代码已经被压缩过了
- 他在压缩之后,代码中所有缩进,注释都会被删除,所以这个插件和BannerPlugin插件只能使用一个,因为代码压缩后,BannerPlugin是没有意义的
webpack-dev-server搭建本地服务器
- webpack提供了一个可选的本地开发服务器,这个本地服务器基于node.js搭建,实现开发中修改源码后需要重新编译
- 它不是一个单独的模块,在webpack中需要安装
npm install --save-dev webpack-dev-server@2.9.1
- devserver也是作为webpack中的一个选项,选项本身可以设置以下属性:
- contentBase:为哪一个文件夹提供本地服务,默认是根文件夹,这里需要填写 ./dist
- port:端口号
- inline:页面实时刷新
- historyApiFallback:在SPA页面中,依赖HTML5的history模式
- webpack.config.js文件配置修改:
const path = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const Webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
//const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
//publicPath: 'dist/'
},
plugins: [
new VueLoaderPlugin(),
new Webpack.BannerPlugin("最终版权归Xiao YouXin所有"),
new HtmlWebpackPlugin({
template: 'index.html'
}),
//new UglifyjsWebpackPlugin()
],
module: {
rules: [
{
test: /\.vue$/,
use: ['vue-loader']
}
]
},
resolve:{
extensions:['.js','.css','.vue'], //配置省略的扩展名
alias:{
'vue#39;: 'vue/dist/vue.esm.js'
}
},
//添加本地服务器配置
devServer:{
contentBase: 'd./dist',
inline: true
}
};
- 在package.json文件中 "scripts"下添加命令映射
"scripts": {
"dev": "webpack-dev-server"
}
- 然后执行命令 npm run dev 就可以启动本地服务,每次修改代码后无须重新编译,点击控制台中的地址就可以打开浏览器
- 也可以在 "dev": "webpack-dev-server" 中添加参数 --open 实现自动打开浏览器
猜你喜欢
- 2024-10-09 Webpack 3.X-4.X升级记录(webpack3升级webpack4)
- 2024-10-09 说说如何借助webpack来优化前端性能?
- 2024-10-09 一个前端项目转换工具(前端怎么转型产品)
- 2024-10-09 网页爬虫之WebPack模块化解密(JS逆向)
- 2024-10-09 Webpack 4.0发布,放弃支持Node.js4,性能大幅提升!
- 2024-10-09 Webpack4 学习 - 04:使用 Plugins 插件
- 2024-10-09 了不起的 Webpack HMR 学习指南(下)「含源码讲解」
- 2024-10-09 webpack5的新特性(webpack5 module federation)
- 2024-10-09 webpack Code Splitting浅析(webpack理解)
- 2024-10-09 如何减 Webpack打包时间,优化Loader,HappyPack,DllPlugin,压缩
- 最近发表
- 标签列表
-
- cmd/c (64)
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- sqlset (59)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)