webpack2教程--从入门到放弃

开车之前,先介绍一些npm的命令:

:D

进入D盘

mkdir webapp

创建webapp文件夹

cd webapp

进入webapp文件夹

mkdir webapp && cd webapp

以上两步创建和进入文件夹可以合并为一步

npm init -y

快速生成package.json文件

npm install xxx --save-dev

//安装模块并加入到开发依赖中,比如webpack

npm install xxx --save

安装模块并加入到生产依赖中,比如Jquery

npm install xxx@2.3.0

下载指定版本

npm view webpack versions --json

如果忘记版本号,可以列出所有版本号

npm install -g cnpm --registry=https://registry.npm.taobao.org

下载淘宝镜像源,国内npm下载很慢,而且有些包下下来貌似会有问题,比如node-sass。

下载之后就可以直接使用了,使用方式跟Npm一样,只不过是改成cnpm

cls

清空命令提示符窗口内容


webpack

1. html篇

介绍完npm基本的东西后,下面开始撸webpack

有关webpack的基本概念建议到官网查看,解释的更为清楚,下面只简单介绍。

1.  在根目录下生成package.json文件: npm init -y

2.  安装webapck cnpm install webpack --save-dev

3. 创建webpack.config.js文件: echo > webpack.config.js


var path=require("path");
module.exports={
<!-- 要打包的文件 -->
entry:"./index.js", output:{
<!-- 指定打包后的文件名字 -->
filename:"bundle.js",
<!-- 打包后的文件路径 -->
path:path.resolve(__dirname,"dist")
}
}
4.创建src目录,并在src目录下创建index.html, index.js文件并随便输一点东西

window.onload=function(){
alert(1)
}
5.执行 webpack 命令,可以发现webpack帮我们在dist下生成了一个main.js文件,打开main.js并拖到最下面你会发现index.js的内容就在里面。

打包完之后,我们在dist生成了js文件,但是我们的index.html在src下面,你可以手动的复制src下的html文件到dist目录下,并且将打包后的js文件引入。不过像我们这么懒的人,还是希望webpack能够帮我们在dist下也生成index.html,要是能自动引入打包后的js文件,那就再好不过了。这时候,是时候来一发插件了。

6.cnpm install html-webpack-plugin --save-dev
修改webpack.config.js
var HtmlWebpackPlugin = require('html-webpack-plugin');
var path = require("path")
module.exports = {
entry:"./index.js",
output: {
path: path.resolve(__dirname, 'dist'),
filename:"bundle.js",
},
plugins: [new HtmlWebpackPlugin({
title: "测试"
})]
};
重新执行命令 webpack ,你会发现在dist下多生成了一个index.html文件,打开发现还有一个script的标签引用着我们打包后的文件,nice。

不过问题又来了,html文件很简陋,就是emmet帮我们生成的Html5文件,你可能希望还带有更多的 meta标签,像这样的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="format-detection" content="telephone=no, email=no"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
</head>
<body>
<header></header>
<nav></nav>
<div id="app"></div>
<footer></footer>
</body>
此时,你可以自己写一个模板,只需要告诉html-webpack-plugin插件文件的位置就可以了。
修改webpack.config.js
plugins: [
new htmlWebpackPlugin({
title:"首页",
<!-- 指定模板位置 -->
template:'./src/index.html',
<!-- 指定打包后的文件名字 -->
filename: 'index.html'
})
]
对于多疑症的你,打包多次后你可能会怀疑文件修改生效了没有,此时你可以安装clean-webpack-plugin插件,在每次打包时,先删除原来的dist目录,再重新打包,这样就可以放心的睡觉,不用担心门没关了。
7.cnpm install clean-webpack-plugin --save-dev
plugins:[
new htmlWebpackPlugin({
title:"首页",
template:'./src/index.html',
filename: 'index.html'
}),
<!-- 每次打包前先删除dist目录 -->
new CleanWebpackPlugin(['dist'])
]

css篇

以往我们写css都是写好后手动通过link引入到html,使用webpack后,你将不再需要手动做这些操作,只需要在js文件中引入,webpack就能帮你搞定,不过需要一些loader和plugin的支持。

cnpm install --save-dev css-loade style-loader

修改webpack.config.js


###为了处理css文件我们需要多配置一个module参数,并使用css-loader来将css文件打包到成“字符串”到js文件中,并使用style-loader将打包后的字符串提取出来并append<style>标签到head下面 

var path=require("path");
var htmlWebpackPlugin=require('html-webpack-plugin');
var CleanWebpackPlugin = require('clean-webpack-plugin'); module.exports={
entry:{
main:'./src/index.js'
},
output:{
filename:"bundle.js",
path:path.resolve(__dirname,'dist')
},
module:{
rules:[
<!-- test检测到以xxx结尾的东西use对应的loader -->
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
}
]
},
plugins:[
new htmlWebpackPlugin({
title:"首页",
template:'./src/index.html',
filename:"index.html"
}),
new CleanWebpackPlugin(['dist'])
]
}
哦,听说你想用sass 预处理 器,那么只需要在use里加多一个sass-loader,并安装依赖
cnpm install --save-dev sass-loader node-sass

rules:[
{
test: /\.scss$/,
use: [ 'style-loader', 'css-loader',"sass-loader" ]
}
]
什么,想要自动补全浏览器后缀autoprefixer?没问题
cnpm install --save-dev  postcss-loader

rules:[
{
test: /\.s?css$/,
use: [
{
loader: "style-loader"
},
{
loader: "css-loader"
},
{
loader: 'postcss-loader',
options: {
plugins: [
require('autoprefixer')({
browsers: ['last 10 versions']
})
]
}
},
{
loader: "sass-loader"
}
]
}
]

这里需要注意,use里面的执行顺序是倒序的 ,,webpack会以倒叙的方式处理并将处理后的结果返回给上一个loader,最后通过style-loader将文件的内容append到head下面的style标签里。

教练,我还想要自动刷新

当你修改一点文件后,你需要重执行命令新编译文件,然后刷新页面。如果你使用过gulp的自动刷新比如live-reload,那你也一定希望webpack也有同样的功能,webpack-dev-server满足你的需求并且能够给你更多。

安装webpack-dev-server到开发依赖  cnpm install --save-dev webpack-dev-server
<!-- 在package.json中加入: -->
"scripts": {
"dev": "webpack-dev-server"
}
通过npm run dev即可执行创建一个服务器,打开localhsot:8080
此时再修改文件,你会发现页面自动刷新了并且修改生效了,不过你看不到重新编译后的文件在哪里,应为webpack-dev-server将文件编译到了内存中 ,比起重新生成文件效率会更高,当然只适用于开发阶段。
启动服务后,如果你 还想让他自己 打开Localhost,还想 使用模块热重载 ,可以加多一个配置
devServer:{
open:true,
hot: true,// 告诉 dev-server我们想用HMR模式
}
开发的时候我们并不在意 style这种形式,但是我们希望在生产环境下 css能从js文件宏分离出来,我们希望能css能跟js并行加载,而且可以避免因为Js文件过大,加载慢而产生的flash of unstyle(无样式页面闪烁)。
使用“extract-text-webpack-plugin”插件来分离css代码。

修改webpack.config.js

cnpm install --save-dev  extract-text-webpack-plugin
var path=require("path");
var webpack=require('webpack');
var htmlWebpackPlugin=require('html-webpack-plugin');
var CleanWebpackPlugin = require('clean-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin"); var extractSass = new ExtractTextPlugin({
filename: "[name].[contenthash].css",
disable: process.env.NODE_ENV === "development"
}); //通过设置环境变量来告诉webpack我们在development模式下不需要提取css到单独在文件,只有当不是development下(也即是production)才需要提取文件。 module.exports={
entry:{
main:'./src/index.js'
},
output:{
filename:"bundle.js",
path:path.resolve(__dirname,'dist')
},
devServer:{
open:true,
hot: true, <!-- 告诉 dev-server我们想用HMR模式 -->
},
module:{
rules:[
{
test: /\.s?css$/,
use: extractSass.extract({ use: [
{
loader: "css-loader"
},
{
loader: 'postcss-loader',
options: {
plugins: [
require('autoprefixer')
]
}
},
{
loader: "sass-loader"
}],
fallback: "style-loader"
})
}
]
},
plugins:[
<!-- 使用此插件来支持热重载 -->
new webpack.HotModuleReplacementPlugin(), new htmlWebpackPlugin({
title:"首页",
template:'./src/index.html',
filename:"index.html"
}),
new CleanWebpackPlugin(['dist']),
extractSass ]
}

修改package.json ,本人为window10系统

"scripts": {
"dev": "set NODE_ENV=development&&webpack-dev-server",
"build":"webpack -p"
}
分别执行npm run dev以及npm run build,你会发先npm run build时css文件被提取到一个单独的文件了。


##js篇
#####--------------------------------好累啊下面直接上代码了

为了使用promise,async等es6,7语法,同时兼容低版本浏览器,你还需要将js转码为es5。

你需要安装以下依赖包
cnpm install --save-dev

    "babel-core": "^6.25.0",
"babel-loader": "^7.0.0",
"babel-plugin-transform-object-rest-spread": "^6.23.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.5.2", 在module下增加:
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['env'],
plugins: ['transform-runtime']
}
}
}

写一点async或者prmise代码,打包后发现promise变成了_promise2


##代理

前后端分离开发时经常还会遇到跨域的问题,还可以利用devServer来进行代理

 devServer:{
open:true,
hot: true,
proxy: {
'/api/': {
target: 'http://baidu.com',
secure: false,
changeOrigin: true
}
} $.ajax({
url:'/api/',
success:function(res){
console.log(res)
},
error:function(res){
console.log(res)
}
})

图片,字体篇

{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 8000,
<!-- 小于8k的转化为Base64 -->
name: '[name].[hash:7].[ext]'
}
}, {
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 8000,
name: 'font/[name].[hash:7].[ext]'
}
}
你可能想要把所有img或者font文件分别放到一个img或者font文件夹下,可以这么写:name: 'img/[name].[hash:7].[ext]'

如果你不想下载字体文件下来,可已上传到阿里字体库并使用阿里的在线字体图标,并复制自己的文件的在线地址。

在css里面像这么用:@import url("//at.alicdn.com/t/font_s0zqwb6by3lhm2t9.css");

打包多文件

var path=require("path");
var webpack=require('webpack');
var htmlWebpackPlugin=require('html-webpack-plugin');
var CleanWebpackPlugin = require('clean-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin"); var extractSass = new ExtractTextPlugin({
filename: "[name].[contenthash].css",
disable: process.env.NODE_ENV === "development"
}); module.exports={
entry:{
"main":'./src/js/index.js',
"car":"./src/js/car.js",
"goods":"./src/js/goods.js"
}, output:{
filename:"[name].[hash].js",
path:path.resolve(__dirname,'dist')
}, devServer:{
open:true,
hot: true,
proxy: {
'/api/': {
target: 'http://baidu.com',
secure: false,
changeOrigin: true
}
} }, module:{
rules:[ {
test: /\.s?css$/,
use: extractSass.extract({
use: [
{
loader: "css-loader"
},
{
loader: 'postcss-loader',
options: {
plugins: [
require('autoprefixer')({
browsers: ['last 10 versions']
})
]
}
},
{
loader: "sass-loader"
}],
fallback: "style-loader"
})
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['env'],
plugins: ['transform-runtime']
}
}
},
{
      test: /\.html$/,
      use: ['html-withimg-loader']
    },
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 8000,
name: 'img/[name].[hash:7].[ext]'
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 8000,
name: 'font/[name].[hash:7].[ext]'
}
}
]
},
plugins:[
new webpack.HotModuleReplacementPlugin(),
new htmlWebpackPlugin({
title:"首页",
template:'./src/index.html',
filename:"index.html",
chunks:["page/main/main"]
}),
new htmlWebpackPlugin({
title:"购物车",
template:'./src/index.html',
filename:"car.html",
chunks:["page/car/car"]
}),
new htmlWebpackPlugin({
title:"商品",
template:'./src/index.html',
filename:"goods.html",
chunks:["page/goods/goods"]
}), new CleanWebpackPlugin(['dist']),
extractSass,
new webpack.ProvidePlugin({
$:"jquery",
jQuery:"jquery"
}) ]
}
上面这样写打包后文件都放在一个目录下,目录很乱,不方便管理,想让每个页面的js,css文件放在对应目录下,可以按下面这么写
entry:{
"page/main/main":'./src/js/index.js',
"page/car/car":"./src/js/car.js",
"page/goods/goods":"./src/js/goods.js"
}
如果多个文件都引用了一些其他库,比如Jquery,vue,你可能想把所有的公共库提取出来,利用common-chunk插件可以解决。即使你做的是spa单页面应用,你也可以将公共库从js文件中提取出来,每次修改时只修改业务逻辑而不重新打包库,从而可以缓存库文件。
entry:{
"main/main":'./src/js/index.js',
"car/car":"./src/js/car.js",
"goods/goods":"./src/js/goods.js"
"vendor":["jquery","vue"]
}, plugins:[
new htmlWebpackPlugin({
...同上
chunks:["page/main/main","vendor","mainfest"]
}), new htmlWebpackPlugin({
...
chunks:["page/car/car","vendor","mainfest"]
}), new htmlWebpackPlugin({
...
chunks:["page/goods/goods","vendor","mainfest"]
}), new webpack.optimize.CommonsChunkPlugin({
name:["vendor","mainfest"]
})
]
发现一个问题,在公司电脑dev-server-open自动打开的地址后面会带undefined,去掉undefined打开网址才正常

代码文件可以上github查看

https://github.com/linrunzheng/webpackGuide

常用的配置就这样了,其他配置可以去webpack官网看。如果觉得本文对你有所帮助,麻烦点个start或者赞

webpack3都出了,你还不会2吗?

上一篇:【公众号系列】两分钟学会SAP F1技巧


下一篇:Apache虚拟主机(三)