入门 Webpack,看这篇就够了

2018年8月25日更新,目前 webpack 已经更新值 4.17.1 ,本文所用到的各种库或多或少有些过时,跟着代码操作下来可能会遇到各种问题,不过 webpack 的主体思想没变,所以还是希望本文对新学 webpack 的你,有所帮助。此外用基于 webpack 4.17.1 写了一个简单的demo,如果遇到啥问题,可以参考,之后应该会逐步来完善这个demo,如果有啥通用的想实现的功能,也可以在里面提 issue

写在前面的话

阅读本文之前,先看下面这个webpack的配置文件,如果每一项你都懂,那本文能带给你的收获也许就比较有限,你可以快速浏览或直接跳过;如果你和十天前的我一样,对很多选项存在着疑惑,那花一段时间慢慢阅读本文,你的疑惑一定一个一个都会消失;如果你以前没怎么接触过Webpack,而你又你对webpack感兴趣,那么动手跟着本文中那个贯穿始终的例子写一次,写完以后你会发现你已明明白白的走进了Webpack的大门。

一个基础的webpack配置文件

// 一个常见的`webpack`配置文件
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin'); module.exports = {
//已多次提及的唯一入口文件
entry: __dirname + "/app/main.js",
output: {
path: __dirname + "/build",
filename: "bundle-[hash].js"
},
devtool: 'none',
devServer: {
contentBase: "./public", //本地服务器所加载的页面所在的目录
historyApiFallback: true, //不跳转
inline: true,
hot: true
},
module: {
rules: [{
test: /(\.jsx|\.js)$/,
use: {
loader: "babel-loader"
},
exclude: /node_modules/
}, {
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: [{
loader: "css-loader",
options: {
modules: true,
localIdentName: '[name]__[local]--[hash:base64:5]'
}
}, {
loader: "postcss-loader"
}],
})
}
}
]
},
plugins: [
new webpack.BannerPlugin('版权所有,翻版必究'),
new HtmlWebpackPlugin({
template: __dirname + "/app/index.tmpl.html" //new 一个这个插件的实例,并传入相关的参数
}),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin(),
new ExtractTextPlugin("style.css")
]
};

什么是WebPack,为什么要使用它?

为什要使用WebPack

WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。

现今的很多网页其实可以看做是功能丰富的应用,它们拥有着复杂的JavaScript代码和一大堆依赖包。为了简化开发的复杂度,前端社区涌现出了很多好的实践方法



① 模块化开发(import,require)

② 预处理(Less,Sass,ES6,TypeScript……)

③ 主流框架脚手架支持(Vue,React,Angular)

④ 庞大的社区(资源丰富,降低学习成本)

这些改进确实大大的提高了我们的开发效率,但是利用它们开发的文件往往需要进行额外的处理才能让浏览器识别,而手动处理又是非常繁琐的,这就为WebPack类的工具的出现提供了需求。 github地址

WebPack和Grunt以及Gulp相比有什么特性

其实Webpack和另外两个并没有太多的可比性,Gulp/Grunt是一种能够优化前端的开发流程的工具,而WebPack是一种模块化的解决方案,不过Webpack的优点使得Webpack在很多场景下可以替代Gulp/Grunt类的工具。

Grunt和Gulp的工作方式是:在一个配置文件中,指明对某些文件进行类似编译,组合,压缩等任务的具体步骤,工具之后可以自动替你完成这些任务。



Webpack的工作方式是:把你的项目当做一个整体,通过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理它们,最后打包为一个(或多个)浏览器可识别的JavaScript文件。

如果实在要把二者进行比较,Webpack的处理速度更快更直接,能打包更多不同类型的文件。

快速开始

创建项目 : 在桌面建立一个文件夹 注: 不要取名webpack,可能会冲突



安装 webpack

安装的时候,不要使用 npm, 否则在 windows 上会失败。 请使用 cnpm

cnpm 是一个国内的镜像

执行

cnpm install -g webpack@1.13.2

如图所示安装结束后,运行

webpack

会看到很多的命令参数,其中,最开始的地方会看到版本 : webpack 1.13.2



main.js

在项目目录下创建 main.js.

这个js 很简单,就是输出一行 “hello webpack”

document.write("hello webpack");

使用 webpack 命令打包

webpack 输入路径 输出路径

在项目目录下运行 : 在当前路径,指定ES6 识别不了的文件, 然后指定打包后的文件

webpack a.js bundle.js



index.html

准备一个 index.html,运用使用这个 bundle.js 文件。bundle就是打包后的文件

<html>
<head>
<script src="bundle.js"></script>
</head>
</html>

打开 index.html

打开 index.html ,即可看到引用 bunlde.js 之后的效果。

如果对文章有疑问的地址建议 去 看看这篇文章 Npm的了解

命令行方式

webpack a.js bundle.js

如果文件名比较复杂,每一次敲入也是比较烦心的事情,所以可以采用配置文件的方式

module.exports = {
entry: './a.js',
output: {
filename: 'bundle.js'
}
};

运行

再次运行,就不需要使用 参数了,而是直接运行 webpack 命令就行了。 因为参数已经都放在 webpack.config.js 文件里面了

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190827193516782.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyODk3NDI3,size_16,color_FFFFFF,t_70

webpack-dev-server 是什么

在前面的例子里,是直接通过浏览器打开 index.html 的页面,这种情况与实际的项目是有区别的,因为实际项目通常都会是在一个服务器上打开 index.html.

webpack-dev-server 是什么呢? 它其实就是一个微服务器,运行它,也就启动了一个 web 服务器,可以方便地从服务器上打开这个 index.html

因为本系列教程里, webpack 是用 cnpm 安装的 1.32.2,考虑到兼容性, webpack-dev-server 也不会安装最新版本,而是与之兼容的版本: webpack-dev-server@1.15.0。

cnpm install -g webpack-dev-server@1.15.0

运行如下命令:

webpack-dev-server --open

会自动打开与 http 协议关联的浏览器,并显示默认的 index.html 页面。

http://localhost:8080/webpack-dev-server/

因为web 服务器总会默认访问 index.html页面,所以就看到了如图所示的效果



端口

默认访问的是8080端口,如果这个端口被占用了,那可以自定义其他端口。

修改 webpack.config.js 为如下代码。

然后重新运行

webpack-dev-derver --open

就会在如图所示的8088端口启动服务器了。

module.exports = {
entry: './a.js',
output: {
filename: 'bundle.js'
},
devServer: {
port:8088
}
}

热更新

webpack-dev-server 支持热更新。 所谓的热更新,即在 webpack.config.js 中的 entry 文件 ( a.js ) 发生了改变之后,会自动运行 webpack, 并且自动刷新页面,立即看到修改之后的效果。

为了做到这一点,需要修改 webpack.config.js 文件。

 var webpack = require('webpack')

因为 webpack 模块是全局的,在某些情况下,通过这种方式导入不能够被识别,需要进行一次链接:

npm link webpack

然后把随后把 webpack.config.js 文件的内容更新如下代码所示。

var webpack = require('webpack')
module.exports = {
entry: './a.js',
output: {
filename: 'bundle.js'
},
plugins:[
new webpack.HotModuleReplacementPlugin()
],
devServer: {
port:8088,
inline:true,
hot:true
}
}

热更新测试

重新启动 webpack-dev-server

webpack-dev-server --open

随便改动一下 a.js 代码,会看到无需刷新 html 页面,自动看到最新的效果。



webpack 中 css 和 html 刷新问题的解决思路

点击查看

npm 启动方式

前面的方式,是直接运行 webpack-dev-server 的方式,不过大都数的项目,都会通过npm 的方式运行。

初始化

运行如下命令进行 package.json 配置文件的初始化

npm init -y

-y 的意思是都同意~ 就不用挨个挨个手动敲打回车了



package.json :

修改 package.json,增加脚本:

 "dev": "webpack-dev-server --open"
{
"name": "webpack-demo",
"version": "1.0.0",
"main": "a.js",
"scripts": {
"dev": "webpack-dev-server --open"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"webpack": "^1.13.2"
},
"devDependencies": {},
"description": ""
}

运行

执行命令:

在scirpt 中是json 格式 (键值对)就相当于运行键

 npm run dev

这样就和单独运行的效果是一样的了

测试

运行测试地址:

http://localhost:8088/

多个入口文件

有时候,会不止一个 js 文件,会有多个。 本知识点就是讲解这种情况下如何进行配置处理

a.js 修改 a.js 为如下代码

document.write("hello webpack from a.js<br>");

b.js

新增 b.js 为如下代码

document.write("hello webpack from b.js<br>");

webpack.config.json

修改配置文件为如下代码。 这回导致 a.js 被打包到 bundle1.js , b.js 被打包到 bundle2.js。

module.exports = {
entry: {
bundle1: './a.js',
bundle2: './b.js'
},
output: {
filename: '[name].js'
},
devServer: {
port:8088
}
}

修改 index.html

修改 index.html 为如下代码, 分别引用两个打包的文件。

<html>
<head>
<script src="bundle1.js"></script>
<script src="bundle2.js"></script>
</head>
</html>

运行测试

npm run dev

webpack Babel-loader

版本兼容问题

本教程建立在 cnpm 安装的如下webpack@1.13.2 和 webpack-dev-server@1.15.0 版本上,其他版本未经测试,不确保可用

cnpm install -g webpack@1.13.2
cnpm install -g webpack-dev-server@1.15.0

es6

ES6 的全称是 ECMAScript 6.0,是下一代的 javascript 语言标准。

因为当前 javascript 标准 (ES5) 对于开发大型的 javascritp 应用支持力度不足够,所以才会推出一个 ES6,期望 js 在大型企业开发领域也有所斩获。

如下代码所示,ES5 和 ES6 在语法上会有区别。

注: ES6 涉及的内容也是非常多的,在本文就不展开讲解了,以后有时间会专门做 ES6 的教程。

es5


var name = "ES5"
document.write(`hello `+ES5)

es6

const name = 'ES6'
document.write(`hello ${name}`)

babel

因为 ES6 标准推出时间还不够久,所以并不是所有的浏览器都支持 ES6 的运行。 因此,需要把 ES6 的 javascript 代码,转换为 ES5 标准的代码,以期能够在当下浏览器上兼容运行。

转换工具有很多种, babel 就是其中的一种。 本文就会讲解如何在 webpack 中使用 babel 工具来进行转换工作。

babel 安装

运行如下命令进行安装。 这些版本号都是经过站长测试,表示能够和当前 webpack@1.32.2 兼容的。

npm install --save-dev babel-loader@6.2.7 babel-core@6.18.0 babel-preset-latest@6.24.1

如果不加版本号。。。对不起,还真就用不起。。。 可见找这些能够匹配 webpack 的babel 版本,可真是累苦博主了

a.js

语法使用 ES6 的写法,这个是无法直接在 浏览器使用的,需要转换为 ES5 才能够使用。

const name = 'ES6'
document.write(`hello ${name}`)

package.config.js

修改 package.config.js:

  1. 入口重新设置为只有 a.js
  2. 出口是 bundle.js
  3. loaders 配置

    3.1 表示仅仅转换 .js 文件
    test: /\.js$/,

    3.2 使用babel loader进行 es6 转换

    	 loader: 'babel',

    3.3 latest 表示用最新的语法规则进行

    query:{
    presets: ['latest']
    }
    module.exports = {
    entry: './a.js',
    output: {
    filename: 'bundle.js'
    },
    devServer: {
    port:8088
    },
    module: {
    loaders: [
    {
    test: /\.js$/,
    loader: 'babel',
    query:{
    presets: ['latest']
    }
    }
    ]
    }

    index.html

    修改回来使用一个 bundle.js

<html>
<head>
<script src="bundle.js"></script>
</head>
</html>

运行 webpack

首先运行 webpack, 会把 a.js 转换为 bundle.js . 此时的 bundle.js 就是已经转换好了的。

打开 bundle.js 翻到最后几行,如图所示就已经是普通的 javascript 语句了。

运行

运行如下命令启动测试:

npm run dev

转换之后,能够识别 ES6。

如图所示

css 模块

在 webpack 的概念里,所有文件都是模块。 所以一个 css 文件也是模块。。。

本文讲解 如何用 css-loader 和 style-loader 把 css 文件作为一个模块打包到 bundle.js 文件里。 (没错。。。 样式也被搞到 js 文件里了。。。)

安装 css-loader 和 style-loader

首先通过如下命令安装 npm install style-loader css-loader --save-dev

npm install style-loader@0.13.1 css-loader@0.25.0 --save-dev

style.css

准备 style.css 文件,效果很简单,就是背景色变成蓝色

body {
background-color: blue;
}

package.config.js

修改 package.config.js,增加 style-loader 和 css-loader。 要使得css 起作用,得同时使用这两个 loader

module.exports = {
entry: './a.js',
output: {
filename: 'bundle.js'
},
devServer: {
port:8088
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel',
query:{
presets: ['latest']
}
},
{
test:/\.css/,
loader:'style-loader!css-loader'
}
]
}
}

a.js

修改a.js ,把 style.css 当作一个模块加进来

require("./style.css")
require("./style.css")
const name = 'ES6'
document.write(`hello ${name}`)

运行

npm run dev

Webpack的学习总结(1)的更多相关文章

  1. WebPack 简明学习教程

    WebPack 简明学习教程 字数1291 阅读22812 评论11 喜欢35 WebPack是什么 一个打包工具 一个模块加载工具 各种资源都可以当成模块来处理 网站 http://webpack. ...

  2. webpack 4 学习资料

    webpack 4 学习资料 资料 网址 webpack 中文版 https://webpack.docschina.org/configuration/ webpack 4 教程 https://s ...

  3. Webpack基础学习

    Webpack基础学习:https://segmentfault.com/a/1190000008853009

  4. gulp + webpack + sass 学习

    笔记: new webpack.optimize.CommonsChunkPlugin 核心作用是抽离公共代码,chunks:['index.js','main.js'] 另一个作用就是单独生成一个j ...

  5. webpack的学习

    什么是webpack? 他有什么优点? 首先对于很多刚接触webpack人来说,肯定会问webpack是什么?它有什么优点?我们为什么要使用它?带着这些问题,我们来总结下如下: Webpack是前端一 ...

  6. webpack入门学习

    一.认识webpack webpack是一款模块打包加载工具.它能够将各种资源.JS.CSS.图片等作为模块打包加载.本人也是近期因工作需要才开始接触webpack,在下文中有误的地方还希望各位能够指 ...

  7. webpack的学习准备工作

    第一步:创建一个空项目,在terminal中 npm init  创建package.json文件,直接回车便可. 第二步:局部安装webpack: npm install --save-dev we ...

  8. webpack初步学习

    https://segmentfault.com/a/1190000006178770 该篇文章足够webpack入门的学习了,对webpack有个初步的了解和认识.

  9. 【Webpack】学习随笔

    参考链接:http://www.runoob.com/w3cnote/webpack-tutorial.html Webpack 是一个前端资源加载/打包工具. Webpack 可以将多种静态资源 j ...

  10. react+webpack基础学习配置

    最近学习react,公司的项目是使用create-react-app来搭建的,而我想重新使用node+mysql+react来搭建一个新的博客. 今天尝试从零开始搭建一个webpack+react项目 ...

随机推荐

  1. JAVA 中的Optional (臭名昭著的空指针异常(NullPointerException))

    从 Java 8 引入的一个很有趣的特性是 Optional  类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) -- 每个 Java 程序员都 ...

  2. MySQL的中的全局锁、表级锁、行锁

    MySQL的中的全局锁.表级锁.行锁 学习极客时间-林晓彬老师-MySQL实战45讲 学习整理 全局锁 对整个数据库实例加锁.通过使用Flush tables with read lock (FTWR ...

  3. Pytest自动化测试 - allure报告进阶

    Allure除了具有Pytest基本状态外,其他几乎所有功能也都支持. 1.严重性 如果你想对测试用例进行严重等级划分,可以使用 @allure.severity 装饰器,它可以应用于函数,方法或整个 ...

  4. PHP AES加密封装类

    简介 PHP AES 加密解密常用封装类 使用方式 $key = 123; $aes = new Aes($key); $data = ['a' => 1]; $aes->decrypt( ...

  5. 【万字长文】Dubbo 入门总结 ,一款高性能的 Java RPC 框架

    这篇文章是我学习整理 Dubbo 的一篇文章,首先大部分内容参考了官网 + 某硅谷的视频,内容讲解进行了重新编排,40多张图片,也都是我修改重制的,虽然一万多字,但是其实也可以看出来,更多的内容集中在 ...

  6. 手写koa-static源码,深入理解静态服务器原理

    这篇文章继续前面的Koa源码系列,这个系列已经有两篇文章了: 第一篇讲解了Koa的核心架构和源码:手写Koa.js源码 第二篇讲解了@koa/router的架构和源码:手写@koa/router源码 ...

  7. 第15.40节、PyQt(Python+Qt)实战:moviepy实现MP4视频转gif动图的工具

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.引言 在写<第15.39节.splitDockWidget和 ...

  8. 第二十一章、 Model/View便利类列表部件QListWidget详解

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 列表部件(List Widget)对应类QListWidget,是从QListView派生 ...

  9. PyQt学习随笔:ListView控件增加列表项

    ListView控件如果需要增加列表项,就是在对应数据存储中插入项,这又分两种情况,一种是已知列表数据存储,一种是未知数据存储.如果是未知数据存储,可以通过: ListView控件名.model() ...

  10. PyQt(Python+Qt)学习随笔:QAbstractItemView的alternatingRowColors属性

    老猿Python博文目录 老猿Python博客地址 alternatingRowColors属性用于控制视图中不同行记录背景色是否使用交替不同的颜色. 如果此属性为True,则将使用QPalette. ...