背景
之前有看过webpack官网,但是学习的一知半解。索性系统学习一下,结果发现已经到了V4版本了,那就直接V4吧。。。。
下载安装
1、安装webpack、webpack-cli
npm init
初始化项目信息
npm install webpack webpack-cli
开始
1、生成目录结构
just-play
|- node_modules
|-...
|- package.json
|- package-lock.json
+ |- index.html
+ |- /src
+ |- index.js
+webpack.config.js
npx webpack
Node 8.2+ 版本提供的 npx 命令,可以运行在初始安装的 webpack 包(package)的 webpack 二进制文件
(./node_modules/.bin/webpack)
2、添加webpack.config.js配置文件
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
在package.json的script中添加命令
默认执行根目录下的webpack.config.js
"scripts": {
"test": "echo test"
"build": "webpack"
},
也可以指定要执行的文件(这种方式在后面的区分开发和生产环境很有用)
"scripts": {
"test": "echo test"
"build": "webpack --config webpack.config.js"
},
3、资源管理,添加loader
样式资源(css、less、sass)、图片资源、字体、xml数据
less依赖less模块所以需要下载less和less-loader
json格式文件已经内置,CSV、TSV 和 XML需要csv-loader xml-loader
npm install style-loader css-loader less less-loader sass-loader file-loader csv-loader xml-loader
webpack.config.js中配置
module: {
rules: [
{
test: /\.(css|less|sass)$/,
use: [
'style-loader',
'css-loader',
'less-loader',
'sass-loader',
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: {
loader: 'file-loader',
options: {
name: './static/images/[name].[hash:8].[ext]',
}
}
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader'
]
},
{
test: /\.(csv|tsv)$/,
use: [
'csv-loader'
]
},
{
test: /\.xml$/,
use: [
'xml-loader'
]
}
]
}
这样基本上完成最初版本的配置,但是上面我们提到区分生产环境和开发环境
4、开发、生产环境
目录结构整理
just-play
|- node_modules
|-...
|- package.json
|- package-lock.json
+ |- index.html
+ |- /src
+ |- index.js
- webpack.config.js
+webpack.dev.js
+webpack.pro.js
+webpack.common.js
webpack.common.js是公共配置文件
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
index: './src/index.js',
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new HtmlWebpackPlugin ()
],
module: {
rules: [
{
test: /\.(css|less|sass)$/,
use: [
'style-loader',
'css-loader',
'less-loader',
'sass-loader',
]
},
...
]
}
};
webpack.pro.js
const webpack = require('webpack');
const merge = require('webpack-merge');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const common = require('./webpack.common.js');
module.exports = merge(common, {
plugins: [
//压缩
new UglifyJSPlugin(),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
})
]
});
webpack.dev.js
const webpack = require('webpack');
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
devtool: 'inline-source-map',
// 使用观察模式 webpack --watch build完成后需要手动刷新
// S使用 webpack-dev-server 开发模式(常用方式) webpack-dev-server --open
devServer: {
contentBase: './src',
hot: true,
},
// E使用 webpack-dev-server 开发模式(常用方式) webpack-dev-server --open
plugins: [
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin(),
]
})
修改package.json中的scrip参数
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --config webpack.prod.js",
"watch": "webpack --watch",
"dev": "webpack-dev-server --open --config webpack.dev.js"
},
!!!!划重点5、插件使用、多页配置以及输出想要的目录结构
目录结构变化
just-play
|- node_modules
|-...
|- package.json
|- package-lock.json
|- publish
|- template.html (生成HTML文件的模板)
+ |- src (index、demo、test三个页面)
|- index
|- main.js
...
|- demo
|- main.js
...
|- test
|-main.js
...
+webpack.dev.js
+webpack.pro.js
+page.js (页面配置map)
+server.js (一种开发模式的依赖)
+webpack.common.js
webpack.common.js
下载相关依赖
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const miniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const pages = require('./page');
// S获取入口map
let entryMap = {};
pages.pageList.map((item) => {
let name = item.name;
let entry = item.entry;
entryMap[name] = entry;
return
});
// E获取入口map
// S输出HTML文件 // 生成build的HTML文件
function getHtmls() {
return pages.pageList.reduce((pre, cur)=>{
let tempArr = [
new HtmlWebpackPlugin({
template: './publish/template.html',
filename: `${cur.name}.html`,
// chunks: [`${cur.name}`, 'commons']
chunks: [`${cur.name}`]
})
]
return pre.concat(tempArr);
}, [])
}
// E输出HTML文件 // 生成build的HTML文件
module.exports = {
entry: {
...entryMap
},
output: {
filename: 'static/js/[name].[hash:8].js',
path: path.resolve(__dirname, 'dist'),
},
// 防止重复,提出公共模块,webpack4提供optimization,低版本使用插件形式
// optimization: {
// splitChunks: {
// cacheGroups: {
// commons: {
// name: 'commons',
// chunks: "initial",
// minChunks: 2
// }
// }
// }
// },
plugins: [
// 分离css(没有分离出css。。。大写的尴尬)
new miniCssExtractPlugin({
filename: '[name].[hash:8].css',
}),
// 删除build之后的文件夹内容
new CleanWebpackPlugin(),
].concat(getHtmls()),
module: {
rules: [
{
test: /\.(css|less|sass)$/,
use: [
'style-loader',
'css-loader',
'less-loader',
'sass-loader',
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: {
loader: 'file-loader',
options: {
name: './static/images/[name].[hash:8].[ext]',
}
}
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader'
]
},
{
test: /\.(csv|tsv)$/,
use: [
'csv-loader'
]
},
{
test: /\.xml$/,
use: [
'xml-loader'
]
}
]
}
};
主要区别在公共配置中
最后build输出的目录结构
|- dist
|- js
...
|- images
...
|- demo.html
|- index.html
|- test.html
完成模块地址:GitHub master分支哦
6、webpack4+vue2项目模块搭建
实际开发中我们一般会使用前端框架去开发我们的项目,现在我们有了webpack帮助我们打包,所以还需要一个前端框架辅助我们开发。现在大火的是vue,那我们就使用webpack4+vue2搭建我们的项目吧。
下载vue相关依赖
npm install vue vue-router vue-loader vue-style-loader vue-template-compiler
webpack.common.js配置更改
loader更改:
module: {
rules: [
{
test: /\.vue$/,
use: [
'vue-loader'
]
},
{
test: /\.(css|less|sass)$/,
use: [
'vue-style-loader',
'style-loader',
'css-loader',
'less-loader',
'sass-loader',
]
},
]
}
插件:
plugins: [
new VueLoaderPlugin(),
]
开发环境编译运行,没有问题,但是build时会报错。
原因:缺少对ES6转换成ES5
解决方案:
npm install babel-core babel-loader@7 babel-preset-es2015
webpack.common.js配置:
rules:[
{
test: /\.(js|ts)$/,
use: [{
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}]
},
]
跟目录下新增 .babelrc文件
内容:
{
"presets": ["es2015"]
}
注意:babel-loader最高8.x,babel-core最高6.x,不指定版本号下载会导致build报错,需要对babel-loader降级处理7.x
详情请见 GitHub dev分支test页面哦
7、webpack4+vue2+typeScript
下载依赖
npm install ts-loader typescript vue-property-decorator
webpack.common.js配置
如下配置后会报 Could not find file: '*.vue.ts' 但是业务vue文件书写ts代码后就没有报错了。。。
官网解释:
> A list of regular expressions to be matched against filename. If
> filename matches one of the regular expressions, a .ts or .tsx suffix
> will be appended to that filename. This is useful for *.vue file
> format for now. (Probably will benefit from the new single file format
> in the future.)。
大致意思是,会给对应文件添加个.ts或.tsx后缀。这也就是报错的找不到vue.ts的由来。
让我们来梳理下ts编译vue 单文件组件的过程:
rules:[
{
test: /\.(ts|tsx)?$/,
use: {
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/],
}
},
exclude: /node_modules/,
},
]
根目录下新增tsconfig.json文件
{
"compilerOptions": {
"outDir": "./dist/",
"noImplicitAny": true,
"module": "es6",
"target": "es5",
"jsx": "react",
"allowJs": true,
"sourceMap": true
},
"exclude": [
"node_modules"
],
}
根目录下新增shims-vue.d.ts文件(这个文件放在哪其实无所谓,斗会扫描到)
declare module '*.vue' {
import Vue from 'vue';
export default Vue;
}
接下来你的业务都可以用vue+ts来开发了
完整示例请见 GitHub webpack4+vue2+ts分支,demo页面哦