注意:webpack配置过程中,版本过新会出现问题,所以注意版本
webpack
webpack 是现代的javascript应用的静态模块打包工具
模块打包
生成浏览器可以识别的文件
前端模块化:ES6 浏览器可以识别
commonJS AMD CMD不能识别,通过webpack 可以打包处理成浏览器可以识别的代码
并且能处理模块间的依赖关系
把CSS、图片、json 文件都可以当做模块来使用
grunt/gulp 核心是Task 前端自动化任务管理工具
没有用到模块化工具,强调前端流程的自动化
webpack 更加强调模块化开发管理,还可以进行文件压缩合并、预处理功能
安装
npm install webpack@3.6.0 -g
1、webpack 要打包的文件 打包后存储的文件
webpack 可以自动处理模块之间的依赖,将相关文件打包成一个浏览器所认识的文件
2、打包入口出口设置
项目初始化npm init 生成 package.json 文件
webpack.config.js ,然后直接在该目录下执行 webpack
const path = require('path');
module.exports={
entry: './src/main.js',
output: {
// 动态获取路径
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
}
}
3、映射
在package.json 文件中进行配置, 运行npm run build 可以执行
在本地安装webpack
npm i webpack@3.6.0 --save-dev
在终端中使用的都是全局的,在映射文件中优先选择局部安装,然后在在全局中寻找
package.json 中的script的脚本在执行过程中,优先寻找本地的node_modules/bin 路径中对应的命令
没有找到,则去全局环境变量中寻找
注意:开发式依赖:
运行式依赖:
{
"name": "meetwebpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
"author": "",
"license": "ISC"
}
loader
转换某些类型的模块是转换器
CSS文件
局部安装:npm i --save-dev css-loader
在webpack.config.js 中配置
错误:UnhandledPromiseRejectionWarning: TypeError: this.getResolve is not a function 原因 css-loader版本过高,更改版本
style-loader 将模块的导出作为样式添加到 DOM 中
css-loader解析 CSS 文件后,使用 import 加载,并且返回 CSS 代码
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' ] //加载顺序,从左到右 注意顺序
}
]
}
}
less文件
安装
npm install --save-dev less-loader less
配置
注意版本,否则报错
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader' ]
},
{
test: /\.less$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader" // compiles Less to CSS
}]
}
]
}
处理图片
npm install --save-dev url-loader
//当加载图片小于limit时候,会将图片编译成base4字符串形式
//党家图片大于limit时候,需要使用file-loader模块进行加载
使用file-loader 时候,将图片打包,重新命名存入配置的disk(导出的文件夹),而图片加载的是当前文件夹下的重命名的打包文件,所以要进行更改
publicPath: 'disk/'
npm install --save-dev file-loader
配置
const path = require('path');
module.exports={
entry: './src/main.js',
output: {
// 动态获取路径
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
//添加打包后图片路径前缀
publicPath: '../dist/'
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader' ]
},
{
test: /\.less$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader" // compiles Less to CSS
}]
},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
//当加载图片小于limit时候,会将图片编译成base4字符串形式
//党家图片大于limit时候,需要使用file-loader模块进行加载
limit: 8192,
//对打包后的名字进行一个限制
name: 'img/[name].[hash:8].[ext]'
},
}
]
}
]
}
}
对ES6的处理
将es6打包为ES5
npm i --save-dev bable-loader@7 babel-core-preset-es2015
{
test: /\.js$/,
//exclude 排除
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
}
对VUE配置
npm i vue --save
env: environment环境
runntime-only 代码中不可以有任何的template
runntime-compiler 代码中有compiler可以编译template
所以要进行配置指定具体文件夹
通过别名指定版本
resolve: {
//alias别名
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
使用方法
import Vue from 'vue';
const app = new Vue({
el:'#app',
data:{
massage: 'helloword'
}
})
.VUE 文件
将组件抽取到.VUE中
npm i vue-loader vue-template-compiler --save-dev
注意版本更改:
{
test: /\.vue$/,
use: ['vue-loader']
}
使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>shdushdufhs</p>
<div id="app">
</div>
<script src="../dist/bundle.js"></script>
</body>
</html>
JS
import Vue from 'vue';
import App from '../vue/cpn.vue';
new Vue({
el:'#app',
template: '<App/>',
data:{
massage: 'helloword'
},
components: {
App
}
})
VUE
<template>
<div>
<p class="title">{{message}}</p>
</div>
</template>
<script>
export default {
name: "cpn",
data(){
return {
message: '你好啊'
}
}
}
</script>
<style scoped>
.title{
background: blue;
}
</style>
整体配置
const path = require('path');
module.exports={
entry: './src/main.js',
output: {
// 动态获取路径
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '../dist/'
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader' ]
},
{
test: /\.less$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader" // compiles Less to CSS
}]
},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
//当加载图片小于limit时候,会将图片编译成base4字符串形式
//党家图片大于limit时候,需要使用file-loader模块进行加载
limit: 8192,
name: 'img/[name].[hash:8].[ext]'
},
}
]
},
{
test: /\.js$/,
//exclude 排除
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
},
{
test: /\.vue$/,
use: ['vue-loader']
}
]
},
resolve: {
extensions: ['.js','.css','.vue'],
//alias别名
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
}
}
plugin
是对webpack本身的扩展,是一个扩展器
BannerPlugin
导入webpack,引入信息
webpack自带的插件
const path = require('path');
const webpack = require('webpack'); //引入webpack
module.exports={
entry: './src/main.js',
output: {
// 动态获取路径
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '../dist/'
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader' ]
},
{
test: /\.less$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader" // compiles Less to CSS
}]
},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
//当加载图片小于limit时候,会将图片编译成base4字符串形式
//党家图片大于limit时候,需要使用file-loader模块进行加载
limit: 8192,
name: 'img/[name].[hash:8].[ext]'
},
}
]
},
{
test: /\.js$/,
//exclude 排除
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
},
{
test: /\.vue$/,
use: ['vue-loader']
}
]
},
resolve: {
//alias别名
alias: {
'vue$': 'vue/dist/vue.esm.js'
},
extensions: ['.js','.css','.vue']
},
//添加插件
plugins: [
new webpack.BannerPlugin('最总版权'); //在打包文件中设置注解
]
}
HtmlWebpackPlugin
自动生成一个index.html 文件可以指定模板来生成
将打包的js文件,通过script标签插到body中
安装:
注意版本, 把添加的路径前缀去掉
npm i html-webpack-plugin --save-dev
const HtmlwebpackPlugin = require('html-webpack-plugin');
plugins: [
new webpack.BannerPlugin('最总版权'),
new HtmlwebpackPlugin({
template: 'indedx.html' //选择的模板,不需要添加script标签会自动添加
})
]
output: {
// 动态获取路径
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
// publicPath: 'dist/' //因为打包了index与打包js文件在一起,不需要此路径
},
uglifyjs
丑化js对js压缩
与BannerPlugin只能用一个,压缩之后注释删去了
npm i uglifyjs-webpack-plugin@1.1.1 --save-dev
const uglifyjswebpack = require('uglifyjs-webpack-plugin');
plugins: [
new webpack.BannerPlugin('最总版权'),
new HtmlwebpackPlugin({
template: 'indedx.html'
}),
new uglifyjswebpack()
]
搭建本地服务器
webpack提供了可选的本地开发服务器,基于node搭建的,内部使用express框架,可以实现浏览器自动刷新显示我们修改后的结果
npm i webpack-dev-server@2.9.3 --save-dev
配置
devServer: {
contentBase: './disk',
inline: true, //页面实时刷新
// port: 端口号,默认8080,
// historyApiFallback: 在spa页面中,依赖HTML5的history模式
},
运行
在package.json 文件中配置
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"dev": "webpack-dev-server"//手动打开
"dev": "webpack-dev-server --open"//自动打开浏览器
},
在本地测试时候,可以通过dev 进行测试,更改文件时候,刷新就可以更改,不需要重新打包,只需在项目完成后执行打包,将打包后的文件进行部署即可
配置文件抽离
有些配置在开发时候用的到,有的在发布时候用的到,有的是公共的所以可以进行抽离
公共的配置:base.config.js
const path = require('path');
const webpack = require('webpack');
const HtmlwebpackPlugin = require('html-webpack-plugin');
const uglifyjswebpack = require('uglifyjs-webpack-plugin');
module.exports={
entry: './src/main.js',
output: {
// 动态获取路径
//设置为上一层,这是为获取当前目录,但是当配置抽离时候,
// 将其放在下一级目录,所有要返回上一级
path: path.resolve(__dirname, '../dist'),
filename: 'bundle.js',
// publicPath: 'dist/'
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader' ]
},
{
test: /\.less$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader" // compiles Less to CSS
}]
},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
//当加载图片小于limit时候,会将图片编译成base4字符串形式
//党家图片大于limit时候,需要使用file-loader模块进行加载
limit: 8192,
name: 'img/[name].[hash:8].[ext]'
},
}
]
},
{
test: /\.js$/,
//exclude 排除
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
},
{
test: /\.vue$/,
use: ['vue-loader']
}
]
},
resolve: {
//alias别名
alias: {
'vue$': 'vue/dist/vue.esm.js'
},
extensions: ['.js','.css','.vue']
},
plugins: [
new webpack.BannerPlugin('最总版权'),
new HtmlwebpackPlugin({
template: 'indedx.html'
})
]
}
开发时候的配置: dev.config.js
const webpackMerge = require('webpack-merge');
const baseConfig = require('./base.config.js');
module.exports = webpackMerge.merge(baseConfig,{
devServer: {
contentBase: './disk',
inline: true, //页面实时刷新
// port:8010 //端口号,默认8080,
// historyApiFallback: 在spa页面中,依赖HTML5的history模式
}
})
发布时候的 prod.config.js
const uglifyjswebpack = require('uglifyjs-webpack-plugin');
const webpackMerge = require('webpack-merge');
const baseConfig = require('./base.config.js');
module.exports = webpackMerge.merge(baseConfig,{
plugins: [
new uglifyjswebpack()
]
})
npm i webpack-merge --save-dev
"build": "webpack --config ./build/prod.config.js",
"dev": "webpack-dev-server --open --config ./build/dev.config.js"
{
"name": "meetwebpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --config ./build/prod.config.js",
"dev": "webpack-dev-server --open --config ./build/dev.config.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"css-loader": "^3.3.1",
"file-loader": "^4.1.0",
"html-webpack-plugin": "^3.2.0",
"less": "^3.12.2",
"less-loader": "^4.1.0",
"style-loader": "^2.0.0",
"uglifyjs-webpack-plugin": "^1.1.1",
"url-loader": "^4.1.1",
"vue-loader": "^13.0.0",
"vue-template-compiler": "^2.6.12",
"webpack": "^3.6.0",
"webpack-dev-server": "^2.9.3",
"webpack-merge": "^5.4.0"
},
"dependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-preset-es2015": "^6.24.1",
"vue": "^2.6.12"
}
}