WebPack4.X 使用指南
一、简介:
webpack是一个前端自动化打包工具,根据它的名字也很好理解,web-pack顾名思义就是前端打包工具;它的使用是基于Node和NPM的,所以在安装使用webpack之前,需要安装nodejs,nodejs的版本过低也不行,所以推荐安装nodejs版本为v8.11.2以上,npm版本为v5.6.0以上;
如何查看node和npm版本?
答:安装完毕nodejs之后,在命令行输入node -v和npm -v查看。
二、项目建立:
第一步:新建一个文件夹,命名为wp。
第二步:在cmd命令行中使用cd命令切入到wp文件夹中,输入npm init或npm init -y,初始化package.json文件;需要注意的是如果package.json的name为webpack可能会引起错误,所以name尽量避免输入为webpack。
如图:
第三步:将wp文件夹拖入到sublime等编辑工具中,并在wp根目录下新建一个webpack.config.js的文件。
webpack.config.js里面应该配置的项目如下:
module.exports = {
entry: '', // 入口文件
output: {}, // 出口文件
module: {}, // 处理对应模块
plugins: [], // 对应的插件
devServer: {}, // 开发服务器配置
mode: 'development' // 模式配置
}
我们先做一个默认配置:
const path = require('path');
module.exports = {
entry: './src/index.js', // 入口文件
output: {
filename: 'bundle.js', // 打包后的文件名称
path: path.resolve('dist') // 打包后的目录,必须是绝对路径
}
}
及将上述所谓的默认配置代码粘贴到webpack.config.js文件中
解释:
所谓的入口文件entry和出口文件output指的都是.js文件,当前的配置是单个入口文件和出口文件,后面我们在配置多页面的时候回有多入口和出口文件。
第四步:根据第三步中的配置内容需要注意到两个路径和文件:
entry: './src/index.js',
filename: 'bundle.js'
path: path.resolve('dist')
'./src/index.js'的意思是在当前wp根目录下要新建一个src文件夹,里面,并且在里面新建一个index.js文件。
filename: 'bundle.js'和path: path.resolve('dist')的意思是最终打包完毕后会在wp根目录下自动创建一个叫dist的文件夹,里面包含一个bundle.js文件
打包前目录结构和代码:
第五步:接下来我们将根据第四步的内容进行打包,要想使用webpack打包,需要使用npm安装webpack 和 webpack-cli,在cmd命令行中输入:
npm install webpack webpack-cli --save-dev
如图:
安装完毕后修改package.json文件中的scripts,如下:
{
"name": "wp",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev" : "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^4.20.2",
"webpack-cli": "^3.1.2"
}
}
然后在cmd命令行中输入npm run dev进行打包。
如下图:
打包后目录结构和代码:
其中增加了一个dist文件夹,里面增加了一个bundle.js文件;这就是之前我们说的输出文件。
第六步:在src目录下新建一个index.html文件,里面引入打包后的bundle.js文件作为测试。
运行后的结果如下:
至此,基于webpack的项目建立好了,接下来我们准备安装一些常用模块和插件。
三、模块和插件配置安装:
1、配置HTML模板
简介
刚才我们建立的index.html文件是在src下面的,但实际打包后的文件是在dist目录下的,我们可以安装一个 html-webpack-plugin 插件,来打包html模板,并将该模板指向对应的入口文件。
安装
npm i html-webpack-plugin -D
配置
修改webpack.config.js后如下:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js', // 入口文件
output: {
filename: 'bundle.js', // 打包后的文件名称
path: path.resolve('dist') // 打包后的目录,必须是绝对路径
},
plugins: [
// 通过new一下这个类来使用插件
new HtmlWebpackPlugin({
// 在src目录下创建一个index.html页面当做模板来用
template: './src/index.html',
})
]
}
增加了插件引入和插件的配置,仔细对比前面的设置就能知道。
运行
运行前修改一下src目录下的index.html代码,取消bundle.js的引用;
再次运行 npm run dev 结果如下:
在dist目录下自动新增了一个index.html文件,并且里面自动引用了bundle.js,这是因为我们新建的index.html文件是自动指向到index.js入口的;而index.js作为入口文件又最终编译生成为bundle.js。
2、引用CSS
简介
css文件在打包完成之后也会输出到dist目录下,所以引用css仍然需要模块支持,我们现在讨论的并不是拆分后的css,而是内部样式表;也就是说,css在自动引入到html文件中的时候是以内部样式表的形式出现的。关于拆分css我们后面会讲到。
安装
引用css需要安装两个模块:style-loader和css-loader
npm i style-loader css-loader -D
其中css-loader是负责解析css的,而style-loader则负责将css以内部样式表的形式嵌入到html中,当使用插件拆分css的时候就不再需要style-loader了,因为那是以外部样式表link到html文件中的。
配置
修改webpack.config.js,增加内容如下:
module: {
rules: [
{
test: /\.css$/, // 解析css
use: ['style-loader', 'css-loader'] // 从右向左解析
/*
也可以这样写,这种方式方便写一些配置参数
use: [
{loader: 'style-loader'},
{loader: 'css-loader'}
]
*/
}
]
}
修改后的webpack.config.js全部内容如下:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js', // 入口文件
output: {
filename: 'bundle.js', // 打包后的文件名称
path: path.resolve('dist') // 打包后的目录,必须是绝对路径
},
plugins: [
// 通过new一下这个类来使用插件
new HtmlWebpackPlugin({
// 在src目录下创建一个index.html页面当做模板来用
template: './src/index.html',
})
],
module: {
rules: [
{
test: /\.css$/, // 解析css
use: ['style-loader', 'css-loader'] // 从右向左解析
/*
也可以这样写,这种方式方便写一些配置参数
use: [
{loader: 'style-loader'},
{loader: 'css-loader'}
]
*/
}
]
}
}
运行
在运行前我们需要在src目录下新建一个css目录,并新建index.css,目录代码如下:
修改index.js,增加:
import "./css/index.css";
运行 npm run dev后的目录代码如下:
目录中并没有增加css文件夹和任何css文件,但是运行dist里面的index.html文件会得到下图效果。
页面效果如下:
这是使用style-loader打包的结果,内部样式表。
3、拆分CSS
简介
通过使用extract-text-webpack-plugin插件将刚才的内部样式表拆分为外部样式表
安装
npm i extract-text-webpack-plugin@next -D
配置
修改webpack.config.js里面的module:
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextWebpackPlugin.extract({
// 将css用link的方式引入就不再需要style-loader了
use: 'css-loader'
})
}
]
},
新增:
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
新增:
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
}),
// 拆分后会把css文件放到dist目录下的css/style.css
new ExtractTextWebpackPlugin('css/style.css')
]
新增new ExtractTextWebpackPlugin('css/style.css') 后,会在dist目录下生产一个css文件夹,且src目录下的css最终会合并到这个style.css文件中,如果不想叫style.css,可以修改。
修改完毕后的webpack.config.js如下:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: './src/index.js', // 入口文件
output: {
filename: 'bundle.js', // 打包后的文件名称
path: path.resolve('dist') // 打包后的目录,必须是绝对路径
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
}),
// 拆分后会把css文件放到dist目录下的css/style.css
new ExtractTextWebpackPlugin('css/style.css')
],
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextWebpackPlugin.extract({
// 将css用link的方式引入就不再需要style-loader了
use: 'css-loader'
})
}
]
}
}
运行
运行 npm run dev后的目录代码如下:
4、引用Less
简介
less作为前端css编译工具广受欢迎,它在前端的使用方式有两种,一种是引入less.js文件来动态编译less代码,这必然是降低了程序的响应时间;第二种就是使用工具或lessc来手动编译转换less代码为css;我们现在要做的事情是在webpack这个自动化工具中配置less,让它变得自动起来。
安装
npm install less less-loader --save-dev
配置
修改webpack.config.js,增加:
{
test:/\.less$/,
use:ExtractTextPlugin.extract({
fallback:"style-loader",
use:[{
loader:"css-loader"
},{
loader:"less-loader"
}]
})
}
修改完毕后的webpack.config.js如下:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: './src/index.js', // 入口文件
output: {
filename: 'bundle.js', // 打包后的文件名称
path: path.resolve('dist') // 打包后的目录,必须是绝对路径
},
plugins: [
// 通过new一下这个类来使用插件
new HtmlWebpackPlugin({
// 在src目录下创建一个index.html页面当做模板来用
template: './src/index.html',
}),
new ExtractTextWebpackPlugin('css/style.css')
],
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextWebpackPlugin.extract({
// 将css用link的方式引入就不再需要style-loader了
use: 'css-loader'
})
},
{
test:/\.less$/,
use:ExtractTextWebpackPlugin.extract({
fallback:"style-loader",
use:[{
loader:"css-loader"
},{
loader:"less-loader"
}]
})
}
]
}
}
运行
运行前需要做的修改如下:
修改src目录下的index.html文件,新增一个class为less的div
在src目录下新建一个less文件夹,并新建index.less文件
在index.js中引入less文件夹下的index.less文件
运行npm run dev后的目录代码如下:
这里的style.css是将index.css和index.less的内容合并后的结果,至于如何拆分开,我们在多入口文件的时候再说。
5、引用Sass
简介
sass引入同less,不再多述。
安装
npm install --save-dev node-sass sass-loader
同时安装了node-sass和sass-loader,其中node-sass安装过程可能会因为国外镜像原因或网络原因出错,但请单独安装node-sass和sass-loader;node-sass安装失败的解决办法主要推荐两个:
第一:
在项目根目录创建.npmrc文件,复制下面代码到该文件。
创建.npmrc文件需要在wp目录下输入命令: type nul>.npmrc
phantomjs_cdnurl=http://cnpmjs.org/downloads
sass_binary_site=https://npm.taobao.org/mirrors/node-sass/
registry=https://registry.npm.taobao.org
保存后 删除之前安装失败的包(第一次安装请跳过此步)
npm uninstall node-sass
重新安装
npm install node-sass
第二:
设置变量 sass_binary_site,指向淘宝镜像地址。示例:
npm i node-sass --sass_binary_site=https://npm.taobao.org/mirrors/node-sass/
// 也可以设置系统环境变量的方式。示例
// linux、mac 下
SASS_BINARY_SITE=https://npm.taobao.org/mirrors/node-sass/ npm install node-sass
// window 下
set SASS_BINARY_SITE=https://npm.taobao.org/mirrors/node-sass/ && npm install node-sass
配置
修改webpack.config.js,新增配置:
{
test: /\.scss$/, // 解析less
// use: ['style-loader', 'css-loader','sass-loader'] // 从右向左解析
use: ExtractTextWebpackPlugin.extract({
// 将css用link的方式引入就不再需要style-loader了
use:[{
loader:"css-loader"
},{
loader:"sass-loader"
}]
})
}
修改后的完整webpack.config.js代码如下:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: './src/index.js', // 入口文件
output: {
filename: 'bundle.js', // 打包后的文件名称
path: path.resolve('dist') // 打包后的目录,必须是绝对路径
},
plugins: [
// 通过new一下这个类来使用插件
new HtmlWebpackPlugin({
// 在src目录下创建一个index.html页面当做模板来用
template: './src/index.html',
}),
new ExtractTextWebpackPlugin('css/style.css')
],
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextWebpackPlugin.extract({
// 将css用link的方式引入就不再需要style-loader了
use: 'css-loader'
})
},
{
test:/\.less$/,
use:ExtractTextWebpackPlugin.extract({
fallback:"style-loader",
use:[{
loader:"css-loader"
},{
loader:"less-loader"
}]
})
},
{
test: /\.scss$/, // 解析less
// use: ['style-loader', 'css-loader','sass-loader'] // 从右向左解析
use: ExtractTextWebpackPlugin.extract({
// 将css用link的方式引入就不再需要style-loader了
use:[{
loader:"css-loader"
},{
loader:"sass-loader"
}]
})
},
]
}
}
运行
运行前需要做的修改如下:
修改src目录下的index.html文件,新增一个class为sass的div
在src目录下新建一个sass文件夹,并新建index.scss文件
在index.js中引入sass文件夹下的index.scss文件
运行npm run dev后的目录代码如下:
这里的style.css是将index.css、index.less和index.scss的内容合并后的结果,至于如何拆分开,我们在多入口文件的时候再说。
6、CSS3自动增加前缀
简介
我们在css或less、sass文件中常常会编写一些CSS3代码,有些时候这些css3代码需要指明私有前缀,这无疑增加了很多工作,可以使用 postcss-loader 插件来帮我们自动增加。
安装
npm install --save-dev postcss-loader autoprefixer
配置
postcss-loader的配置不同于前面的几个文件,它需要在wp根目录下新建一个postcss.config.js文件,并在里面添加如下代码:
module.exports = {
plugins: [require('autoprefixer')] // 引用该插件即可了
}
然后对需要的css或less、sass模块做出修改,比如你需要在css中增加css3前缀的功能,那就在css模块中增加postcss-loader,如下:
{
test: /\.css$/, // 解析css
use: ExtractTextWebpackPlugin.extract({
use:[{
loader:"css-loader"
},{
loader:"postcss-loader"
}],
})
},
less模块和sass模块操作同理。
修改后的webpack.config.js代码如下:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: './src/index.js', // 入口文件
output: {
filename: 'bundle.js', // 打包后的文件名称
path: path.resolve('dist') // 打包后的目录,必须是绝对路径
},
plugins: [
// 通过new一下这个类来使用插件
new HtmlWebpackPlugin({
// 在src目录下创建一个index.html页面当做模板来用
template: './src/index.html',
}),
new ExtractTextWebpackPlugin('css/style.css')
],
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextWebpackPlugin.extract({
// 将css用link的方式引入就不再需要style-loader了
// use: 'css-loader'
use:[{
loader:"css-loader"
},{
loader:"postcss-loader"
}],
})
},
{
test:/\.less$/,
use:ExtractTextWebpackPlugin.extract({
fallback:"style-loader",
use:[{
loader:"css-loader"
},{
loader:"less-loader"
}]
})
},
{
test: /\.scss$/, // 解析less
// use: ['style-loader', 'css-loader','sass-loader'] // 从右向左解析
use: ExtractTextWebpackPlugin.extract({
// 将css用link的方式引入就不再需要style-loader了
use:[{
loader:"css-loader"
},{
loader:"sass-loader"
}]
})
},
]
}
}
运行
运行前修改src/css/index.css文件,增加了transform css3代码,如下:
运行 npm run dev 后的目录代码如下:
刚刚修改的css3代码,自动增加了私有前缀。
7、CSS中的图片引用处理
简介
css中引用图片主要引用file-loader和url-loader,其中file-loader主要解决引用路径问题,url-loader主要解决图片的加载优化问题,可以设置一个阈值,比如将8k以下的图片转换为data-url的形式直接引用到html文件中,从而减少请求次数,达到优化目的。
安装
npm install --save-dev file-loader url-loader
配置
修改webpack.config.js,增加如下代码:
{
test: /\.(jpe?g|png|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192, // 小于8k的图片自动转成base64格式,并且不会存在实体图片
outputPath: 'images/' // 图片打包后存放的目录
}
}
]
},
并增加红框中的内容
修改后的webpack.config.js文件如下:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: './src/index.js', // 入口文件
output: {
filename: 'bundle.js', // 打包后的文件名称
path: path.resolve('dist') // 打包后的目录,必须是绝对路径
},
plugins: [
// 通过new一下这个类来使用插件
new HtmlWebpackPlugin({
// 在src目录下创建一个index.html页面当做模板来用
template: './src/index.html',
}),
new ExtractTextWebpackPlugin('css/style.css')
],
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextWebpackPlugin.extract({
// 将css用link的方式引入就不再需要style-loader了
// use: 'css-loader'
use:[{
loader:"css-loader"
},{
loader:"postcss-loader"
}],
publicPath: '../'
})
},
{
test:/\.less$/,
use:ExtractTextWebpackPlugin.extract({
fallback:"style-loader",
use:[{
loader:"css-loader"
},{
loader:"less-loader"
}]
})
},
{
test: /\.scss$/, // 解析less
// use: ['style-loader', 'css-loader','sass-loader'] // 从右向左解析
use: ExtractTextWebpackPlugin.extract({
// 将css用link的方式引入就不再需要style-loader了
use:[{
loader:"css-loader"
},{
loader:"sass-loader"
}]
})
},
{
test: /\.(jpe?g|png|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192, // 小于8k的图片自动转成base64格式,并且不会存在实体图片
outputPath: 'images/' // 图片打包后存放的目录
}
}
]
},
]
}
}
运行
运行前在src目录下新建image文件夹,在文件夹当中放一个图片做测试,如图:
修改src目录下的index.html文件:
修改src/css/index.css文件
运行 npm run dev后的效果为:
8、HTML中的图片引用处理
简介
同css中的图片处理,在html文件中使用img标签引用图片同样存在类似问题,需要安装 html-withimg-loader 模块
安装
npm install --save-dev html-withimg-loader
配置
修改webpack.config.js文件,新增:
{
test: /\.(htm|html)$/,
use: 'html-withimg-loader'
}
运行
修改src目录下的 index.html文件新增img标签
运行 npm run dev 后的效果如图:
9、iconfont字体引用
简介
原理同上
安装
不需要安装,因为已经安装过file-loader了。
配置
修改webpack.config.js文件,新增:
{
test: /\.(eot|ttf|woff|svg)$/,
use: 'file-loader'
},
运行
拷贝一个iconfont字体图标库到src/css文件夹下,如图:
在src/index.html文件中新增 span标签如下:
在src/index.js文件新增 iconfont.css引入如下:
运行 npm run dev 后的效果如下:
页面中将增加一个麦当劳的M标志,证明成功使用了字体图标。
10、Babel安装
简介
ES6因为包含广泛,ES2015,2016,2017等,使用中对ES6的转码是必须的,所以我们采用了babel来转码。
安装
npm install --save-dev babel-core babel-loader babel-preset-react babel-preset-env
这个安装过程可能比较慢,也可能会出现一些关于Parse , Json等的解析错误,出现类似的错误请按照下面两个方法解决:
第一:
运行 : npm cache clean –force 之后再运行上面的安装命令。
第二:
如果问题没有顺利解决,运行:npm install --registry=https://registry.npm.taobao.org --loglevel=silly
之后再运行安装命令。
配置
修改webpack.config.js,新增:
{
test:'/\.(js|jsx)$/',
use: 'bable-loader',
include: /src/, // 只转化src目录下的js
exclude: /node_modules/ // 排除掉node_modules,优化打包速度
}
运行
运行前,在wp根目录下新建.babelrc文件
type nul>.babelrc
并在里面新增如下代码:
{
"presets": ["env", "stage-0"] // 从右向左解析
}
目录代码如下:
运行 npm run dev后观察代码的变化,事实上没有安装babel的时候,webpack也可以解码es6,但考虑到es6代表广泛,所以还是安装了babel解码。
11、JS代码压缩
在webpack.config.js中新增:
mode: 'development'
表示开发环境,不压缩代码。
mode: 'production'
表示生产环境,压缩代码。
12、CSS代码压缩
简介
CSS代码压缩需要安装插件:
optimize-css-assets-webpack-plugin
安装
npm install optimize-css-assets-webpack-plugin --save-dev
配置
在webpack.config.js中新增
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
和
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.css$/g,
cssProcessor: require('cssnano'),
cssProcessorOptions: { safe: true, discardComments: { removeAll: true } },
canPrint: true
})
目录代码如图:
运行
运行 npm run dev 后的目录代码如下:
13、HTML代码压缩
html代码压缩不用再安装额外的插件和模块,修改webpack.config.js中的html插件为:
new HtmlWebpackPlugin({
template: './src/index.html',
//filename: 'index.html',
//chunks: ['index'], // 对应关系,index.js对应的是index.html
minify: {
removeAttributeQuotes:true,
removeComments: true,
collapseWhitespace: true,
removeScriptTypeAttributes:true,
removeStyleLinkTypeAttributes:true
}
}),
目录代码如图:
运行 npm run dev后可见dist目录下的index.html已经压缩了。
14、安装第三方类库Jquery
简介
jquery作为前端必需的第三方类库,安装是它是一个示范作用,其他的第三方类库安装可以参考jquery 的安装。
安装
npm install jquery --save-dev
配置
jquery的引用要用到webpack,所以修改webpack.config.js,新增:
const Webpack = require('webpack');
还要新增:
new Webpack.ProvidePlugin({
$:'jquery'
}),
备注:如果项目还引用了Bootstrap,那jquery的配置还需要修改为如下:
new Webpack.ProvidePlugin({
$:'jquery',
jQuery:'jquery'
}),
修改后的webpack.config.js代码如下:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const Webpack = require('webpack');
module.exports = {
mode: 'development',//production
entry: './src/index.js', // 入口文件
output: {
filename: 'bundle.js', // 打包后的文件名称
path: path.resolve('dist') // 打包后的目录,必须是绝对路径
},
plugins: [
// 通过new一下这个类来使用插件
// new HtmlWebpackPlugin({
// // 在src目录下创建一个index.html页面当做模板来用
// template: './src/index.html',
// }),
new HtmlWebpackPlugin({
template: './src/index.html',
//filename: 'index.html',
//chunks: ['index'], // 对应关系,index.js对应的是index.html
minify: {
removeAttributeQuotes:true,
removeComments: true,
collapseWhitespace: true,
removeScriptTypeAttributes:true,
removeStyleLinkTypeAttributes:true
}
}),
new ExtractTextWebpackPlugin('css/style.css'),
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.css$/g,
cssProcessor: require('cssnano'),
cssProcessorOptions: { safe: true, discardComments: { removeAll: true } },
canPrint: true
}),
new Webpack.ProvidePlugin({
$:'jquery'
})
],
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextWebpackPlugin.extract({
// 将css用link的方式引入就不再需要style-loader了
// use: 'css-loader'
use:[{
loader:"css-loader"
},{
loader:"postcss-loader"
}],
publicPath: '../'
})
},
{
test:/\.less$/,
use:ExtractTextWebpackPlugin.extract({
fallback:"style-loader",
use:[{
loader:"css-loader"
},{
loader:"less-loader"
}]
})
},
{
test: /\.scss$/, // 解析less
// use: ['style-loader', 'css-loader','sass-loader'] // 从右向左解析
use: ExtractTextWebpackPlugin.extract({
// 将css用link的方式引入就不再需要style-loader了
use:[{
loader:"css-loader"
},{
loader:"sass-loader"
}]
})
},
{
test: /\.(jpe?g|png|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192, // 小于8k的图片自动转成base64格式,并且不会存在实体图片
outputPath: 'images/' // 图片打包后存放的目录
}
}
]
},
{
test: /\.(htm|html)$/,
use: 'html-withimg-loader'
},
{
test: /\.(eot|ttf|woff|svg)$/,
use: 'file-loader'
},
{
test:'/\.(js|jsx)$/',
use: 'bable-loader',
include: /src/, // 只转化src目录下的js
exclude: /node_modules/ // 排除掉node_modules,优化打包速度
}
]
},
}
运行
运行前修改src目录下的index.js文件,新增:
$('div').css('border', '10px solid white');
目录代码如下:
运行npm run dev后的效果如下:
15、多页面多入口打包
在实际的开发中,我们不可能只有一个页面,常常需要很多页面,那打包多页面就很实际了,多页面就需要多入口,也就是需要多个.js文件;所以在src目录下新建:login.html和login.js,其中login.js作为login.html页面的入口文件。
在src/css下新建login.css文件作为修饰login.html的css,目录代码如图:
login.html
login.css
login.js
新增完毕页面后,还需要修改webpack.config.js文件:
修改入口文件为:
修改出口文件为:
修改html插件为:
修改css插件为:
修改后的webpack.config.js代码如下:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const Webpack = require('webpack');
module.exports = {
mode: 'development',//production
// entry: './src/index.js', // 入口文件
entry: {
index: './src/index.js',
login: './src/login.js'
},
// output: {
// filename: 'bundle.js', // 打包后的文件名称
// path: path.resolve('dist') // 打包后的目录,必须是绝对路径
// },
output: {
filename: '[name].js',
path: path.resolve('dist')
},
plugins: [
// 通过new一下这个类来使用插件
// new HtmlWebpackPlugin({
// // 在src目录下创建一个index.html页面当做模板来用
// template: './src/index.html',
// }),
// new HtmlWebpackPlugin({
// template: './src/index.html',
// // filename: 'index.html',
// // chunks: ['index'], // 对应关系,index.js对应的是index.html
// minify: {
// removeAttributeQuotes:true,
// removeComments: true,
// collapseWhitespace: true,
// removeScriptTypeAttributes:true,
// removeStyleLinkTypeAttributes:true
// }
// }),
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html',
chunks: ['index'], // 对应关系,index.js对应的是index.html
minify: {
removeAttributeQuotes:true,
removeComments: true,
collapseWhitespace: true,
removeScriptTypeAttributes:true,
removeStyleLinkTypeAttributes:true
}
}),
new HtmlWebpackPlugin({
template: './src/login.html',
filename: 'login.html',
chunks: ['login'], // 对应关系,login.js对应的是login.html
minify: {
removeAttributeQuotes:true,
removeComments: true,
collapseWhitespace: true,
removeScriptTypeAttributes:true,
removeStyleLinkTypeAttributes:true
}
}),
// new ExtractTextWebpackPlugin('css/style.css'),
new ExtractTextWebpackPlugin('css/[name].css'),
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.css$/g,
cssProcessor: require('cssnano'),
cssProcessorOptions: { safe: true, discardComments: { removeAll: true } },
canPrint: true
}),
new Webpack.ProvidePlugin({
$:'jquery'
})
],
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextWebpackPlugin.extract({
// 将css用link的方式引入就不再需要style-loader了
// use: 'css-loader'
use:[{
loader:"css-loader"
},{
loader:"postcss-loader"
}],
publicPath: '../'
})
},
{
test:/\.less$/,
use:ExtractTextWebpackPlugin.extract({
fallback:"style-loader",
use:[{
loader:"css-loader"
},{
loader:"less-loader"
}]
})
},
{
test: /\.scss$/, // 解析less
// use: ['style-loader', 'css-loader','sass-loader'] // 从右向左解析
use: ExtractTextWebpackPlugin.extract({
// 将css用link的方式引入就不再需要style-loader了
use:[{
loader:"css-loader"
},{
loader:"sass-loader"
}]
})
},
{
test: /\.(jpe?g|png|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192, // 小于8k的图片自动转成base64格式,并且不会存在实体图片
outputPath: 'images/' // 图片打包后存放的目录
}
}
]
},
{
test: /\.(htm|html)$/,
use: 'html-withimg-loader'
},
{
test: /\.(eot|ttf|woff|svg)$/,
use: 'file-loader'
},
{
test:'/\.(js|jsx)$/',
use: 'bable-loader',
include: /src/, // 只转化src目录下的js
exclude: /node_modules/ // 排除掉node_modules,优化打包速度
}
]
},
}
运行 npm run dev 后的 dist目录结构如下:
16、优化多页面多入口
由于每次新增一个页面都需要修改webpack.config.js这很麻烦,所以修改后的webpack.config.js如下:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
const Webpack = require('webpack');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const glob = require("glob");
var webpackConfig = {
mode: 'development',//production
// entry: './src/index.js', // 单页面入口文件
// 多页面配置
entry: {
index: './src/index.js',
login: './src/login.js'
},
// 出口文件
output: {
filename: '[name].js',
path: path.resolve('dist')
},
plugins: [
new ExtractTextWebpackPlugin('css/[name].css'),
new Webpack.ProvidePlugin({
$:'jquery'
}),
new Webpack.HotModuleReplacementPlugin(),//调用webpack的热更新插件
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.css$/g,
cssProcessor: require('cssnano'),
cssProcessorOptions: { safe: true, discardComments: { removeAll: true } },
canPrint: true
})
],
module: {
rules: [
{
test: /\.css$/, // 解析css
// use: ['style-loader', 'css-loader'] // 从右向左解析
use: ExtractTextWebpackPlugin.extract({
// 将css用link的方式引入就不再需要style-loader了
// use: 'css-loader',
use:[{
loader:"css-loader"
},{
loader:"postcss-loader"
}],
publicPath: '../'
})
},
{
test: /\.less$/, // 解析less
// use: ['style-loader', 'css-loader','less-loader'] // 从右向左解析
use: ExtractTextWebpackPlugin.extract({
// 将css用link的方式引入就不再需要style-loader了
use:[{
loader:"css-loader"
},{
loader:"less-loader"
}]
})
},
{
test: /\.scss$/, // 解析less
// use: ['style-loader', 'css-loader','sass-loader'] // 从右向左解析
use: ExtractTextWebpackPlugin.extract({
// 将css用link的方式引入就不再需要style-loader了
use:[{
loader:"css-loader"
},{
loader:"sass-loader"
}]
})
},
{
test: /\.(jpe?g|png|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192, // 小于8k的图片自动转成base64格式,并且不会存在实体图片
outputPath: 'images/' // 图片打包后存放的目录
}
}
]
},
{
test: /\.(htm|html)$/,
use: 'html-withimg-loader'
},
{
test: /\.(eot|ttf|woff|svg)$/,
use: 'file-loader'
},
{
test:'/\.(js|jsx)$/',
use: 'bable-loader',
include: /src/, // 只转化src目录下的js
exclude: /node_modules/ // 排除掉node_modules,优化打包速度
}
]
}
}
function getView(globPath){
let files = glob.sync(globPath);
let entries = {},
entry, dirname, basename, pathname, extname;
files.forEach(item => {
entry = item;
dirname = path.dirname(entry);//当前目录
extname = path.extname(entry);//后缀
basename = path.basename(entry, extname);//文件名
pathname = path.join(dirname, basename);//文件路径
if (extname === '.html') {
entries[pathname] = './' + entry;
} else if (extname === '.js') {
entries[basename] = entry;
}
});
return entries;
}
let pages = Object.keys(getView('./src/*html'));
pages.forEach((pathname) => {
let htmlname = pathname.split('src/')[1];
let conf = {
filename: `${htmlname}.html`,
template: `${pathname}.html`,
// hash: true,
chunks:[htmlname],
minify: {
removeAttributeQuotes:true,
removeComments: true,
collapseWhitespace: true,
removeScriptTypeAttributes:true,
removeStyleLinkTypeAttributes:true
}
}
webpackConfig.plugins.push(new HtmlWebpackPlugin(conf));
});
module.exports = webpackConfig;
除此之外不用修改其他任何文件。
17、热更新
简介
每次运行和更新代码都输入npm run dev命令太麻烦,安装热更新来解决该问题,每次改动代码后,只需要保存代码并刷新页面即可,不用再执行命令。
安装
npm install webpack-dev-server --save-dev
配置
修改webpack.config.js 新增插件:
new Webpack.HotModuleReplacementPlugin(),//调用webpack的热更新插件
新增热更新配置:
devServer: {
// 设置服务器访问的基本目录
contentBase:path.resolve(__dirname,'dist'), //最好设置成绝对路径
// 设置服务器的ip地址,可以是localhost
host:'localhost',
// 设置端口
port:8090,
// 设置自动打开浏览器
open:true,
// 设置热更新
hot:true
}
修改后的webpack.config.js如下:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
const Webpack = require('webpack');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const glob = require("glob");
var webpackConfig = {
mode: 'development',//production
// entry: './src/index.js', // 单页面入口文件
// 多页面配置
entry: {
index: './src/index.js',
login: './src/login.js'
},
// 出口文件
output: {
filename: '[name].js',
path: path.resolve('dist')
},
plugins: [
new ExtractTextWebpackPlugin('css/[name].css'),
new Webpack.ProvidePlugin({
$:'jquery'
}),
new Webpack.HotModuleReplacementPlugin(),//调用webpack的热更新插件
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.css$/g,
cssProcessor: require('cssnano'),
cssProcessorOptions: { safe: true, discardComments: { removeAll: true } },
canPrint: true
})
],
module: {
rules: [
{
test: /\.css$/, // 解析css
// use: ['style-loader', 'css-loader'] // 从右向左解析
use: ExtractTextWebpackPlugin.extract({
// 将css用link的方式引入就不再需要style-loader了
// use: 'css-loader',
use:[{
loader:"css-loader"
},{
loader:"postcss-loader"
}],
publicPath: '../'
})
},
{
test: /\.less$/, // 解析less
// use: ['style-loader', 'css-loader','less-loader'] // 从右向左解析
use: ExtractTextWebpackPlugin.extract({
// 将css用link的方式引入就不再需要style-loader了
use:[{
loader:"css-loader"
},{
loader:"less-loader"
}]
})
},
{
test: /\.scss$/, // 解析less
// use: ['style-loader', 'css-loader','sass-loader'] // 从右向左解析
use: ExtractTextWebpackPlugin.extract({
// 将css用link的方式引入就不再需要style-loader了
use:[{
loader:"css-loader"
},{
loader:"sass-loader"
}]
})
},
{
test: /\.(jpe?g|png|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192, // 小于8k的图片自动转成base64格式,并且不会存在实体图片
outputPath: 'images/' // 图片打包后存放的目录
}
}
]
},
{
test: /\.(htm|html)$/,
use: 'html-withimg-loader'
},
{
test: /\.(eot|ttf|woff|svg)$/,
use: 'file-loader'
},
{
test:'/\.(js|jsx)$/',
use: 'bable-loader',
include: /src/, // 只转化src目录下的js
exclude: /node_modules/ // 排除掉node_modules,优化打包速度
}
]
},
devServer: {
// 设置服务器访问的基本目录
contentBase:path.resolve(__dirname,'dist'), //最好设置成绝对路径
// 设置服务器的ip地址,可以是localhost
host:'localhost',
// 设置端口
port:8090,
// 设置自动拉起浏览器
open:true,
// 设置热更新
hot:true
}
}
function getView(globPath){
let files = glob.sync(globPath);
let entries = {},
entry, dirname, basename, pathname, extname;
files.forEach(item => {
entry = item;
dirname = path.dirname(entry);//当前目录
extname = path.extname(entry);//后缀
basename = path.basename(entry, extname);//文件名
pathname = path.join(dirname, basename);//文件路径
if (extname === '.html') {
entries[pathname] = './' + entry;
} else if (extname === '.js') {
entries[basename] = entry;
}
});
return entries;
}
let pages = Object.keys(getView('./src/*html'));
pages.forEach((pathname) => {
let htmlname = pathname.split('src/')[1];
let conf = {
filename: `${htmlname}.html`,
template: `${pathname}.html`,
// hash: true,
chunks:[htmlname],
minify: {
removeAttributeQuotes:true,
removeComments: true,
collapseWhitespace: true,
removeScriptTypeAttributes:true,
removeStyleLinkTypeAttributes:true
}
}
webpackConfig.plugins.push(new HtmlWebpackPlugin(conf));
});
module.exports = webpackConfig;
修改wp根目录下的package.json文件:
修改后的package.json如下:
{
"name": "wp",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack --mode development",
"dev": "webpack-dev-server --mode development"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"autoprefixer": "^9.1.5",
"babel-core": "^6.26.3",
"babel-loader": "^8.0.4",
"babel-preset-env": "^1.7.0",
"babel-preset-stage-0": "^6.24.1",
"css-loader": "^1.0.0",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"file-loader": "^2.0.0",
"html-webpack-plugin": "^3.2.0",
"html-withimg-loader": "^0.1.16",
"jquery": "^3.3.1",
"less-loader": "^4.1.0",
"node-sass": "^4.9.3",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"postcss-loader": "^3.0.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"url-loader": "^1.1.2",
"webpack": "^4.20.2",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.9"
}
}
运行
运行 npm run dev 后的cmd命令行效果如下:
18、安装Vue
简介
vue是在使用中,我们对组件模板的引用有一种单文件模板的使用形式,这种模板的引用就需要用到ES6的模块技术,所以将vue打包到webpack里面。
安装
安装vue:
npm install vue --save-dev
安装vue-loader和vue-template-compiler
npm install vue-loader vue-template-compiler --save-dev
配置
修改webpack.config.js:
新增:
...
const VueLoaderPlugin = require('vue-loader/lib/plugin');
...
new VueLoaderPlugin(),
...
{ test: /\.vue$/, use: 'vue-loader' },
...
resolve: {
alias: {
'vue': 'vue/dist/vue.js'
}
}
...
修改后的代码示例如下:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const Webpack = require('webpack');
module.exports = {
entry: './src/index.js', // 入口文件
output: {
filename: 'bundle.js', // 打包后的文件名称
path: path.resolve('dist') // 打包后的目录,必须是绝对路径
},
plugins: [
// 通过new一下这个类来使用插件
new HtmlWebpackPlugin({
// 在src目录下创建一个index.html页面当做模板来用
template: './src/index.html',
}),
new VueLoaderPlugin(),
new Webpack.HotModuleReplacementPlugin(),//调用webpack的热更新插件
],
module: {
rules: [
{
test:'/\.(js|jsx)$/',
use: 'bable-loader',
include: /src/, // 只转化src目录下的js
exclude: /node_modules/ // 排除掉node_modules,优化打包速度
},
{ test: /\.vue$/, use: 'vue-loader' },
]
},
devServer: {
// 设置服务器访问的基本目录
contentBase:path.resolve(__dirname,'dist'), //最好设置成绝对路径
// 设置服务器的ip地址,可以是localhost
host:'localhost',
// 设置端口
port:8090,
// 设置自动打开浏览器
open:true,
// 设置热更新
hot:true
},
resolve: {
alias: {
'vue': 'vue/dist/vue.js'
}
}
}
运行
输入npm run dev运行查看效果,这里不再列出.vue的编写和vue相关的引入了。直接查看示例即可。