提示: 文中代码片段可能会在本文上传后格式被压缩,感兴趣的童鞋请复制代码到ide中格式化后查看,敬请谅解!
![webpack使用干货](http://www.yixao.com/wp-content/themes/exou/themer/assets/images/lazy.png)
webpack
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$\': \'vue/dist/vue.esm.js\'
} }};
- 这时能正常使用vue相关内容
- html代码:
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
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:`
<h2>{{message}}h2>
div>
`,
data:{ message: \'hellow vue\',
}, methods:{ }});
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
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$\': \'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$\': \'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$\': \'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$\': \'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$\': \'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 实现自动打开浏览器
内容出处:,
声明:本网站所收集的部分公开资料来源于互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时修改或删除。文章链接:http://www.yixao.com/procedure/11777.html