webpack的基本使用

webpack 本质上是一个打包工具,它会根据代码的内容解析模块依赖,帮助我们把多个模块的代码打包。借用 webpack 官网的图片:

虽然webpack4.x的版本可以零配置开始构建,但是在实际的项目中需要其它的一些功能,还是需要一个配置文件。

安装

下面一步一步讲解配置一个基本的前端开发环境过程。

首先自己环境中安装了有node(自带npm)。如果你的项目中没有package.json,那么需要使用npm init。

会在项目下生成一个package.json文件,其中会有如下代码:

{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

我们现在来使用npm来安装webpack,可以作为一个全局的命令来使用:

npm install webpack webpack-cli -g 

其中webpack-cli是使用webpack的命令行工具。在 4.x 版本之后不再作为 webpack 的依赖了,我们使用时需要单独安装这个工具。

更多的时候我们是把webpack作为项目的依赖来安装使用的。

npm install webpack webpack-cli -D 

package.json文件就会多了如下配置:

"devDependencies": {
"webpack": "^4.27.1",
"webpack-cli": "^3.1.2"
}

我们在package.json中添加一个npm scripts:

代码如下:

"scripts": {
"build": "webpack --mode production"
},
"devDependencies": {
"webpack": "^4.27.1",
"webpack-cli": "^3.1.2"
}

然后我们创建一个'./src/index.js',其中index.js中的代码任意写,如:

export default {
a:'字符串'
}

然后执行npm run build后会在项目下增加了一个dist文件夹,里面存放了webpack构建好的main.js文件。

因为是作为项目依赖进行安装,所以不会有全局的命令,npm 会帮助我们在当前项目依赖中寻找对应的命令执行,如果是全局安装的 webpack,直接执行webpack --mode production就可以。

webpack重要的几个概念

webpack 的几个重要的概念:入口,loader,plugin,输出。

入口

所谓入口,就是webpack的构建入口。webpack会读取这个文件,并从它这儿开始解析依赖,然后进行打包。如上面操作,一开始webpack默认的构建入口就是'./src/index.js'。

在我们的项目中,如果是单页面应用,一般就只有一个入口;如果是多页面,那么就会配置成一个页面一个构建入口。

入口可以使用entry字段来设置,webpack支持配置多个入口进行构建打包:

module.exports = {
entry: './src/index.js'
} // 上述配置等同于
module.exports = {
entry: {
main: './src/index.js'
}
} // 或者配置多个入口
module.exports = {
entry: {
foo: './src/page-foo.js',
bar: './src/page-bar.js',
// ...
}
} // 使用数组来对多个文件进行打包
module.exports = {
entry: {
main: [
'./src/foo.js',
'./src/bar.js'
]
}
}

最后的例子,可以理解为多个文件作为一个入口,webpack 会解析两个文件的依赖后进行打包。

loader

webpack 中提供一种处理多种文件格式的机制,便是使用 loader。我们可以把 loader 理解为是一个转换器,负责把某种文件格式的内容转换成 webpack 可以支持打包的模块。

举个例子,比如你的入口文件index.js引入了css样式,那么构建的时候就需要用css-loader来处理这些.css文件,同时还需要style-loader。最终打包的结果就是把不同类型的文件都解析成js代码,以便在打包后能在浏览器中运行。

当我们需要使用不同的 loader 来解析处理不同类型的文件时,我们可以在module.rules字段下配置相关的规则,比如使用babel来转化js代码:

module: {
// ...
rules: [
{
test: /\.jsx?/, // 匹配文件路径的正则表达式,通常我们都是匹配文件类型后缀
include: [
path.resolve(__dirname, 'src') // 指定哪些路径下的文件需要经过 loader 处理
],
use: 'babel-loader', // 指定使用的 loader
},
],
}

后面有笔记会详细记录下loader的使用以及怎样开发loader。

plugin

在webpack的构建工作中,除了用loader来处理模块代码的转换,剩下的工作就是用plugin来完成,下面列举常用的几个:

  • 压缩JS代码:uglifyjs-webpack-plugin
  • 关联JS生成html页面:html-webpack-plugin
  • 生成CSS文件: extract-text-webpack-plugin
  • 定义环境变量:DefinePlugin

JS代码压缩配置如下:

const UglifyPlugin = require('uglifyjs-webpack-plugin')

module.exports = {
plugins: [
new UglifyPlugin()
],
}

输出

webpack 的输出即指 webpack 最终构建出来的静态文件。构建结果的文件名、路径等都是可以配置的,使用output字段:

module.exports = {
// ...
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
} // 或者多个入口生成不同文件
module.exports = {
entry: {
foo: './src/foo.js',
bar: './src/bar.js',
},
output: {
filename: '[name].js',
path: __dirname + '/dist',
},
} // 路径中使用 hash,每次构建时会有一个不同 hash 值,避免发布新版本时线上使用浏览器缓存
module.exports = {
// ...
output: {
filename: '[name].js',
path: __dirname + '/dist/[hash]',
},
}

我们刚开始构建的webpack,默认的构建结果就是'./dist/main.js'。

一个简单的webpack配置例子

上面总结了几个webpack的重要概念后,来看一个简单的配置例子,webpack运行时默认读取项目下的webpack.config.js文件作为配置,那么我们现在就在项目下创建一个webpack.config.js文件:

const path = require('path')
const UglifyPlugin = require('uglifyjs-webpack-plugin') //js压缩插件 module.exports = {
entry:'./src/index.js', output:{
path:path.resolve(__dirname,'dist'),
filename:'bundle.js'
}, module:{
rules:[
{
test:/\.jsx?/,//匹配js,jsx文件
include:[
path.resolve(__dirname,'src')
],
use:'babel-loader'
}
]
}, // 代码模块路径解析的配置
resolve: {
modules: [
"node_modules",
path.resolve(__dirname, 'src')
], extensions: [".wasm", ".mjs", ".js", ".json", ".jsx"],
}, plugins:[
new UglifyPlugin() //使用uglifyjs-webpack-plugin压缩JS代码
//根据上面第一次的构建,你会发现webpack默认使用了JS的代码压缩插件
//这其实也是命令中的 --mode production的效果
]
}

当你直接运行npm run build命令的时候,会报错Cannot find module 'uglifyjs-webpack-plugin'。这儿你需要安装如下内容:

  • 1.npm install uglifyjs-webpack-plugin --save-dev
  • 2.npm install -D babel-loader@7 babel-core babel-preset-env webpack
  • 3.最后执行npm run build能看到在dist文件夹下生成了一个bundle.js构建完成的文件。

vue脚手架vue-cli的webpack配置

vue-cli 使用 webpack 模板生成的项目文件中,webpack 相关配置存放在 build 目录下。现在的脚手架vue-cli的webpack好像还是用的webpack3.x版本,要注意下版本区别。

构建基本的前端开发环境

我们构建基本的前端开发环境需要做哪些事情:

  • 构建我们发布需要的 HTML、CSS、JS 文件
  • 使用 CSS 预处理器来编写样式
  • 处理和压缩图片
  • 使用 Babel 来支持 ES 新特性
  • 本地提供静态服务以方便开发调试

下面围绕这些要求要构建开发环境。

JS关联HTML页面html-webpack-plugin

当我们构建打包完成生成了JS文件,怎样把JS文件跟html页面相关联呢,也就是html怎样引入js文件。当然可以使用script标签引入js文件,但是如果打包构建的js路径变化或者使用了hash命名,那么直接引入js文件就不合理了,这时就需要使用html-webpack-plugin

把html-webpack-plugin安装到项目依赖中去:

npm install html-webpack-plugin -D 

首先自己按照下列目录创建模板html文件,‘./src/assets/index.html’,html内容随便写,如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>这是构建的第一个web页面</title>
</head>
<body>
</body>
</html>

将html-webpack-plugin配置到webpack.config.js中的plugins列表中:

module.exports = {
// ...
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html', // 配置输出文件名和路径
template: 'assets/index.html', // 配置文件模板
}),
],
}

这样,通过 html-webpack-plugin 就可以将我们的页面和构建 JS 关联起来,这样将会产生一个包含以下内容的文件dist/index.html。打开index.html可以看到构建后的代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>这是构建的第一个web页面</title>
</head>
<body>
<script type="text/javascript" src="bundle.js"></script></body>
</html>

详细了解可参考文档html-webpack-plugin, 官网提供的例子html-webpack-plugin/examples/

构建CSS

我们构建CSS需要使用css-loader和style-loader。

module.exports = {
module: {
rules: [
// ...
{
test: /\.css/,
include: [
path.resolve(__dirname, 'src'),
],
use: [
'style-loader',
'css-loader',
],
},
],
}
}

注:style-loader 和 css-loader 都是单独的 node package,需要安装。

我们创建一个index.css,在index.js中引入:

import './index.css'

index.css里面随便编写一段css代码:

.title{
font-weight: bold;
font-size:20px;
color:red;
}

模板index.html改成如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<div class="title">这是一个主题</div>
</body>
</html>

安装style-loader与css-loader:

npm install style-loader css-loader --save-dev

现在执行npm run build,然后去看生成的index.html,效果有了,css样式添加上了。但是并没有生成css文件。

解释下css-loader跟style-loader的作用:

  • css-loader 负责解析 CSS 代码,主要是为了处理 CSS 中的依赖,例如@import和url()等引用外部文件的声明;
  • style-loader 会将 css-loader 解析的结果转变成 JS 代码,运行时动态插入style标签来让 CSS 代码生效。

如果需要单独把 CSS 文件分离出来,我们需要使用extract-text-webpack-plugin.

由于webpack4.x的extract-text-webpack-plugin版本还没有发布正式版,安装的时候需要指定使用它的 alpha 版本:

npm install extract-text-webpack-plugin@next -D

配置:

const ExtractTextPlugin = require('extract-text-webpack-plugin')

module.exports = {
// ...
module: {
rules: [
{
test: /\.css$/,
// 因为这个插件需要干涉模块转换的内容,所以需要使用它对应的 loader
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader',
}),
},
],
},
plugins: [
// 引入插件,配置文件名,这里同样可以使用 [hash]
new ExtractTextPlugin('index.css'),
],
}

然后就会在dist文件夹下多生成一个index.css文件。详细可参考:extract-text-webpack-plugin

CSS 预处理器

通常我们在编写css的时候,经常使用less或者sass等css预处理器,我们以less为例,我们把index.css改成index.less如下:

@fontSize:20px;
.title{
font-weight: bold;
font-size:@fontSize;
color:red;
}

安装less-loader,官网文档对应loader:

npm install --save-dev less-loader less

对应的配置文件修改为:

module.exports = {
// ...
module: {
rules: [
{
test: /\.less$/,
// 因为这个插件需要干涉模块转换的内容,所以需要使用它对应的 loader
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'css-loader',
'less-loader',
],
}),
},
],
},
// ...
}

处理图片文件file-loader及增强版url-loader

file-loader

虽然css-loader会解析样式中用url()引用的文件路径,但是图片有jpg/png/gif格式,webpack处理不了,需要使用一个loader配置才行,这就用到了file-loader。

file-loader 可以用于处理很多类型的文件,它的主要作用是直接输出文件,把构建后的文件路径返回。

配置如下:

module.exports = {
// ...
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {},
},
],
},
],
},
}

安装file-loader,官方文档file-loader:

npm install --save-dev file-loader

我在index.js引入一张图片:

import '../assets/a.jpg'

运行结果默认在dist目录下生成了78414f2de9fc47d29f335727a717bc3d.jpg。默认情况下,生成的文件的文件名就是文件内容的 MD5 哈希值并会保留所引用资源的原始扩展名。

当然也可以配置输出路径,文件名称等,如下:

{
test:/\.(jpg|png|gif)$/,
use:[
{
loader:'file-loader',
options:{
name: '[path][name].[ext]',
outputPath: 'images/'
}
}
]
}

url-loader

安装url-loader,详细文档请参考官网url-loader

url-loader功能类似于file-loader,但是在文件大小(单位 byte)低于指定的限制时,可以返回一个 DataURL。

npm install --save-dev url-loader

配置:

module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
}
}
]
}
]
}
}

使用 Babel

Babel是一个让我们能够使用 ES 新特性的 JS 编译工具,我们可以在 webpack 中配置 Babel,以便使用 ES6、ES7 标准来编写 JS 代码。

前面已经写过配置了,代码如下:

module.exports = {
// ...
module: {
rules: [
{
test: /\.jsx?/, // 支持 js 和 jsx
include: [
path.resolve(__dirname, 'src'), // src 目录下的才需要经过 babel-loader 处理
],
loader: 'babel-loader',
},
],
},
}

Babel 的相关配置可以在目录下使用 .babelrc 文件来处理,详细参考 Babel 官方文档 .babelrc

使用 webpack-dev-server启动静态服务

我们可以使用 webpack-dev-server在本地开启一个简单的静态服务来进行开发。

安装webpack-dev-server:

npm install webpack-dev-server --save-dev

然后添加启动命令到 package.json 中:

"scripts": {
"build": "webpack --mode production",
"start": "webpack-dev-server --mode development"
}

然后运行npm run start,然后就可以访问 http://localhost:8080/ 来查看你的页面了。默认是访问 index.html,如果是其他页面要注意访问的 URL 是否正确。

总结

根据上面的配置,我们已经完成了配置一个简单的前端开发环境,实现了:构建 HTML、CSS、JS 文件、使用 CSS 预处理器来编写样式、处理和压缩图片、使用 Babel、方便开发调试的静态服务。下面的笔记会记录webpack的一些细节来更好的了解webpack。



webpack4.x笔记-配置基本的前端开发环境(一)的更多相关文章

  1. angular学习笔记(2)- 前端开发环境

    angular1学习笔记(2)- 前端开发环境 1.代码编辑工具 2.断点调试工具 3.版本管理工具 4.代码合并和混淆工具 5.依赖管理工具 6.单元测试工具 7.集成测试工具 常见的前端开发工具 ...

  2. 总结:Mac前端开发环境的搭建(配置)

    新年新气象,在2016年的第一天,我入手了人生中第一台自己的电脑(大一时好友赠送的电脑在一次无意中烧坏了主板,此后便不断借用别人的或者网站的).macbook air,身上已无分文...接下来半年的房 ...

  3. 用 Docker 快速配置前端开发环境

    来源于:http://dockone.io/article/1714 今天是你入职第一天. 你起了个大早,洗漱干净带着材料去入职. 签了合同,领了机器,坐到工位,泡一杯袋装红茶,按下开机键,输入密码, ...

  4. AngularJS + CoffeeScript 前端开发环境配置详解

    AngularJS 号称 '第一框架' ('The first framework') 确实是名不虚传.由其从jQuery中完全转入AngularJS后就有无法离开他的感觉了.虽然AngularJS的 ...

  5. 用grunt搭建web前端开发环境

    1.前言 本文章旨在讲解grunt入门,以及讲解grunt最常用的几个插件的使用. 2.安装node.js Grunt和所有grunt插件都是基于nodejs来运行的,如果你的电脑上没有nodejs, ...

  6. 【Yeoman】热部署web前端开发环境

    本文来自 “简时空”:<[Yeoman]热部署web前端开发环境>(自动同步导入到博客园) 1.序言 记得去年的暑假看RequireJS的时候,曾少不更事般地惊为前端利器,写了<Sp ...

  7. 【前端福利】用grunt搭建自动化的web前端开发环境-完整教程

    jQuery在使用grunt,bootstrap在使用grunt,百度UEditor在使用grunt,你没有理由不学.不用! 1. 前言 各位web前端开发人员,如果你现在还不知道grunt或者听说过 ...

  8. 转:【前端福利】用grunt搭建自动化的web前端开发环境-完整教程

    原文地址:http://blog.csdn.net/wangfupeng1988/article/details/46418203 jQuery在使用grunt,bootstrap在使用grunt,百 ...

  9. 用grunt搭建自动化的web前端开发环境实战教程(详细步骤)

    用grunt搭建自动化的web前端开发环境实战教程(详细步骤) jQuery在使用grunt,bootstrap在使用grunt,百度UEditor在使用grunt,你没有理由不学.不用!前端自动化, ...

随机推荐

  1. Java核心技术梳理-基础类库

    一.引言 Oracle为Java提供了丰富的基础类库,Java 8 提供了4000多个基础类库,熟练掌握这些基础类库可以提高我们的开发效率,当然,记住所有的API是不可能也没必要的,我们可以通过API ...

  2. 游戏服务器h2engine架构优化和跨平台设计

    H2engine的GitHub星星不知不觉已经破百了,也没有特意推广过,但是慢慢的关注的人越来越多.因为事情多,好久没有写东西了,前一段时间有了一些想法,把h2engine又更新了一下,感觉h2eng ...

  3. 设计模式系列19:策略模式(Stragety Pattern)

    定义 定义一系列算法,将它们一个个封装起来,并且使它们可以互相替换,该模式使得算法可独立于使用它的客户而变化.    --<设计模式>GoF UML类图 使用场景 一个系统有许多类,而区分 ...

  4. vue表格实现固定表头首列

    前言 最近在做vue移动端项目,需要做一个可以固定表头首列的表格,而且由于一些原因不能使用任何UI插件,网上找了很久也没什么好方法,所以在解决了问题之后,写下了这篇文章供后来人参考,文章有什么错漏的问 ...

  5. Python之路【第五篇】:Python基础之文件处理

    阅读目录 一.文件操作 1.介绍 计算机系统分为:计算机硬件,操作系统,应用程序三部分. 我们用python或其他语言编写的应用程序若想要把数据永久保存下来,必须要保存于硬盘中,这就涉及到应用程序要操 ...

  6. CentOS 查看和修改 Mysql 字符集

    客户提供了 mysql 的环境,但是不支持中文,通过以下命令查看了 mysql 的字符集 mysql> show variables like 'character_set%'; 显示如下: + ...

  7. Feign源码解析

    1. Feign源码解析 1.1. 启动过程 1.1.1. 流程图 1.1.2. 解释说明 Feign解析过程依赖Spring的初始化,它通过实现ImportBeanDefinitionRegistr ...

  8. Android USB Headset: Device Specification

    For USB headsets to work seamlessly across the Android ecosystem, Android devices must support them ...

  9. 开发人员的必备工具Git(初级)

    Git是什么 Git是目前世界上最先进的分布式版本控制系统. 这个软件用起来就应该像这个样子,能记录每次文件的改动: 举个栗子 :       版本 用户 说明 日期 1 张三 删除了软件服务条款5 ...

  10. 【朝花夕拾】Android安全之(一)权限篇

    前言        从Android6.0开始,Android系统对权限的处理产生了很大的变化.如果APP运行的设备系统版本为Android6.0或更高,并且target在23或更高,那么danger ...