Webpack学习笔记

webpack学习笔记

1 入门示例

1.1 新建入门项目

通过npm init命令新建一个项目:

$ npm init -y
npm init -y
Wrote to /home/deepin/Desktop/doc/webpack/demo01/package.json:

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

1.2 安装webpack和webpack-cli

通过npm install命令安装webpack和webpack-cli:

npm install webpack webpack-cli --save-dev 

> webpack-cli@3.3.2 postinstall /home/deepin/Desktop/doc/webpack/demo01/node_modules/webpack-cli
> node ./bin/opencollective.js



                            Thanks for using Webpack!
                 Please consider donating to our Open Collective
                        to help us maintain this package.



                 Donate: https://opencollective.com/webpack/donate


npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN demo01@1.0.0 No description
npm WARN demo01@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.9 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.9: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

+ webpack-cli@3.3.2
+ webpack@4.32.2
added 390 packages from 217 contributors and audited 5231 packages in 65.573s
found 0 vulnerabilities

这里要注意的是,我是通过在项目中安装的方式来安装webpack的,而不是全局安装,这样的好处就是我们在每次执行webpack命令时都是以项目中的webapck版本为主。

1.3 新建要通过webpack打包的文件

webpack默认打包的文件是./src/index.js,所以我们在项目根目录新建一个src目录,并在src目录下新建一个index.js文件:

import Hello from './hello'
alert("hello webpack...")
new Hello()

上面index.js中引入了hello.js,所以index.js所在目录下新建一个index.js文件:

export default function Hello() {
    console.log('hello ...')
}

1.4 使用webpack打包

在项目根目录执行npx webpack命令:

$ npx webpack
Hash: 9f774ffb74e02491827e
Version: webpack 4.32.2
Time: 184ms
Built at: 2019-05-23 19:40:09
  Asset       Size  Chunks             Chunk Names
main.js  955 bytes       0  [emitted]  main
Entrypoint main = main.js
[0] ./src/index.js 25 bytes {0} [built]

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/

命令执行完后会在当前项目下生成dist/main.jsmain.js就是我们打包后的文件了。

1.5 引用打包后的文件

在项目目录下新建一个index.html文件,引入main.js

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<!-- 引用打包文件 -->
<script src="./dist/main.js"></script>
</body>
</html>

完成上述所有操作后,在浏览器中执行该html文件,就会发现js文件中的代码被执行了。

2 基本知识

2.1 关于执行npx webpack

如果我们在命令行中只是执行了webpack命令,那么程序会去查找系统中安装的webpack,也就是全局安装的webpack,由于我们是局部安装的 webpack,所以通过npx命令就能执行项目中的webpack命令,即程序会找当前项目下的./node_modules/.bin/webpack执行,而执行webpack命令又需要webpack-cli,所以也要安装webpack-cli

2.2 webpack基本配置

2.2.1 配置输入输出

由示例程序我们知道webpack默认打包项目目录下的./src/index.js文件,打包后的输出文件是./dist/main.js。那么我们如果想修改配置要怎么做呢?webpack的默认配置文件一般是webpack.config.js,我们在项目目录下新建一个webpack.config.js,并键入如下内容:

const path = require('path')
module.exports = {
    // 指定输入文件
    entry: './src/access.js',
    // 指定输出文件
    output: {
        // 输出文件的文件名
        filename: 'bundle.js',
        // 输出文件路径
        path: path.resolve(__dirname, "build")
    }
}

重新执行webpack打包命令,我们将会看到在项目根目录生成一个build/bundle.js。我们在index.html中引入该文件,并在浏览器中执行,我们会发现access.js被执行了。

2.2.2 配置模式

我们打开打包后的文件可以看到打包的文件是被压缩了的,我们也可以在配置文件中配置mode属性配置来指定打包是否压缩:

const path = require('path')
module.exports = {
	// 配置模式 
    mode: 'production',
    // 指定输入文件
    entry: './src/access.js',
    // 指定输出文件
    output: {
        // 输出文件的文件名
        filename: 'bundle.js',
        // 输出文件路径
        path: path.resolve(__dirname, "build")
    }
}
  • development:会将 process.env.NODE_ENV 的值设为 development。启用 NamedChunksPlugin 和 NamedModulesPlugin。
  • production:会将 process.env.NODE_ENV 的值设为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 UglifyJsPlugin.
  • none:没有应用任何插件

2.3 配置静态服务

2.3.1 安装webpack-dev-server

webpack-dev-server提供了静态服务能力,我们通过npm来安装:

npm install webpack-dev-server -D
2.3.2 启动静态服务

通过执行webpack-dev-server命令就可以启动服务:

$ npx webpack-dev-server
ℹ 「wds」: Project is running at http://localhost:8081/
ℹ 「wds」: webpack output is served from /
ℹ 「wds」: Content not from webpack is served from /home/deepin/Desktop/doc/webpack/demo01
ℹ 「wdm」: Hash: ee964693b814a03fffa1
Version: webpack 4.32.2
Time: 271ms
Built at: 2019-05-24 15:32:31
    Asset     Size  Chunks             Chunk Names
bundle.js  349 KiB    main  [emitted]  main
Entrypoint main = bundle.js
[0] multi (webpack)-dev-server/client?http://localhost ./src/access.js 40 bytes {main} [built]
[./node_modules/ansi-html/index.js] 4.16 KiB {main} [built]
[./node_modules/events/events.js] 13.3 KiB {main} [built]
[./node_modules/html-entities/index.js] 231 bytes {main} [built]
[./node_modules/loglevel/lib/loglevel.js] 7.68 KiB {main} [built]
[./node_modules/node-libs-browser/node_modules/punycode/punycode.js] 14.3 KiB {main} [built]
[./node_modules/querystring-es3/index.js] 127 bytes {main} [built]
[./node_modules/url/url.js] 22.8 KiB {main} [built]
[./node_modules/webpack-dev-server/client/index.js?http://localhost] (webpack)-dev-server/client?http://localhost 9.26 KiB {main} [built]
[./node_modules/webpack-dev-server/client/overlay.js] (webpack)-dev-server/client/overlay.js 3.59 KiB {main} [built]
[./node_modules/webpack-dev-server/client/socket.js] (webpack)-dev-server/client/socket.js 1.05 KiB {main} [built]
[./node_modules/webpack-dev-server/node_modules/strip-ansi/index.js] (webpack)-dev-server/node_modules/strip-ansi/index.js 161 bytes {main} [built]
[./node_modules/webpack/hot sync ^\.\/log$] (webpack)/hot sync nonrecursive ^\.\/log$ 170 bytes {main} [built]
[./node_modules/webpack/hot/emitter.js] (webpack)/hot/emitter.js 75 bytes {main} [built]
[./src/access.js] 18 bytes {main} [built]
    + 11 hidden modules
ℹ 「wdm」: Compiled successfully.

从打印的日志中我们可以看到服务已经在http://localhost:8081/端口启动了,在浏览器中访问该地址,就能访问到项目根目录。(注:如果项目根目录有index.html文件,会访问该文件,否则否此目录)。

2.3.3 配置静态服务启动脚本

我们每次启动静态服务器时都要输入npx webpack-dev-server来启动,我们也可以自定义指定启动,类似开vue中的npm run serve,我们在package.jsonscripts字段中配置"serve": "webpack-dev-server"

{
  "name": "demo01",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    // 这里是我们配置的静态服务器
    "serve": "webpack-dev-server"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^4.32.2",
    "webpack-cli": "^3.3.2",
    "webpack-dev-server": "^3.4.1"
  }
}

配置好后,我们可以通过执行npm run serve来启动静态服务。同样的我们在执行webpack打包的时候执行的是npx webpack,我们也能配置成npm run build来执行打包, 如下 :

{
  "name": "demo01",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "serve": "webpack-dev-server",
    // 配置webpack 打包
    "build": "webpack" 
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^4.32.2",
    "webpack-cli": "^3.3.2",
    "webpack-dev-server": "^3.4.1"
  }
}

注:webpack.config.js是webpack默认的配置文件名字,我们可以通过在执行webpack命令时指定使用哪个配置文件,如npx webpack --config my.config.js

2.3.4 配置具体静态服务配置

我们可以在webpack.config.js(webpack配置文件中)添加devServer属性来配置静态服务器:

const path = require('path')
module.exports = {
    devServer: {
        // 指定启动端口
        port: 9000,
        // 启动时添加进度条
        progress: true,
        // 静态服务访问根目录
        contentBase: './html/',
        // 采用gzip压缩
        compress: true
    },
    mode: 'production',
    // 指定输入文件
    entry: './src/access.js',
    // 指定输出文件
    output: {
        // 输出文件的文件名
        filename: 'bundle.js',
        // 输出文件路径
        path: path.resolve(__dirname, "build")
    }
}

我们看一下这个目录contentBase: './html/',,这个目录就是配置的当我们访问服务端口时,会访问这个目录下的index.html文件,如果不配置这个目录的话默认访问的就是项目根目录下的index.html文件。

2.4 配置插件

2.4.1 配置html-webpack-plugin插件
  • 安装插件npm install
$ npm installl html-webpack-plugin -D
  • 配置
    插件在plugins字段中配置,template属性指定要配置的html模块文件(要被打包的html文件),该文件会被自动引入打包后的.js文件,filename字段指定打包后的html文件的名字。
const path = require('path')
let HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    devServer: {
        // 指定启动商品
        port: 9000,
        // 启动时添加进度条
        progress: true,
        // 静态服务访问根目录
        contentBase: './html/',
        // 采用gzip压缩
        compress: true
    },
    mode: 'production',
    // 指定输入文件
    entry: './src/access.js',
    // 指定输出文件
    output: {
        // 输出文件的文件名
        filename: 'bundle.js',
        // 输出文件路径
        path: path.resolve(__dirname, "build")
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html',
            filename: 'index.html'
        })
    ]
}

注意:contentBase: './html/',我们指定了静态服务器的默认访问路径是./thml/目录,但是静态服务会优先访问HtmlWebpackPlugin打包后的目录(注:这个目录在运行npx webpack-dev-server时并没有生成)。为了更好的理解,请看下面所示:

-项目根目录
	- html
		- index.html
		- test.html
	- build
		- index.html
		- bundle.js
		- test.html

项目有如下目录,我们通过启动npx wepack-dev-server并在浏览器中访问启动项目(假设项目端口为8000),也就是localhost:8000会访问到build/index.html,如果访问localhost:8000/bundle.js会访问到build/bundle.js,如果访问localhost:8000/test.html会访问到html/test.html,也就是说服务优先访问打包目录中文件。
我们更改一下项目中的内容,删除html/test.html,即:

-项目根目录
	- html
		- index.html
	- build
		- index.html
		- bundle.js
		- test.html

我们再访问localhost:8000/test.html就访问不到了,说明我们访问的不是打包后生成的目录,为了验证我们的说法,我们删除build目录:

- html
		- index.html

我们启动项目,我们同样做前面所示的各种访问。

  • 更多配置
// 要导入.
const HtmlWebpackPlugin = require('html-webpack-plugin')


plugins: [
       new HtmlWebpackPlugin({
           template: './src/index.html',
           filename: 'main.html',
           minify: {
               // 除去打包后的html中的双引号操作 
               removeAttributeuotes: true,
               // 除去打包后的html中的空白符
               collapseWhitespace: true
           },
           // 打包后的html文件引入的打包的js后面加上hash串
           hash: true
       })
   ]

补充:我们也可以在打包生成的.js文件名中生成hash,如下 我们在打包生成的js文件名中生成了一个截取8个字符长度的hash串(就像这样:bundle.4bf4c7f9.js):

output: {
        // 输出文件的文件名
        filename: 'bundle.[hash:8].js',
        // 输出文件路径
        path: path.resolve(__dirname, "build")
    },

2.5 配置模块

webapck默认只支持js打包,如果想要配置css等其他模块的打包需要配置模块对应的loader来实现。对于各个loader的配置,是在webpack的配置文件中的module/rules属性中配置的,如下:

module.exports = {
	module: {
		rules: [
		]
	}
}
2.5.1 配置打包css

这里用一个新的项目作演示(npm init)。

  • 安装html-webpack-plugin
	npm install html-webpack-plugin -D
  • 配置html-webpack-plugin
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
   plugins : [
       new HtmlWebpackPlugin({
           template: './src/index.html'
       })
   ]
}
  • 新建main.css
@import './color.css';
body {
    background: gray;
}
  • 新建color.css
body {
    color: whitesmoke;
}
  • 安装css-loader
    css-loader用于解析css语法并打包css文件,通过npm安装css-loaer:
$ npm install css-loader -D
  • 安装style-loader
    style-loader用来把css文件插入到html文件的header标签中,安装:
$ npm install style-loader -D
  • 配置css-loaderstyle-loader
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    plugins : [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ],
    module: { // 在这下面配置loder
        rules: [ //  配置loader使用规则
            {
                test: /\.css$/, // loader 要应用到哪些文件上,接收正则表达式
                use: ["style-loader","css-loader"] // 要应用的loader,注意是从后向前执行,先解析css再插入css
            }
        ]
   }
}
  • 新建index.jsindex.html
    src下新建index.js并引入main.css
import './main.css'

src下新建index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    hello world!
</body>
</html>
  • 执行npx webpack打包
    执行命令npx webpack打包,会在dist目录下生成main.jsindex.html两个文件,并在浏览器中运行index.html,会看到index.html中的header中的样式部分如下(浏览器中,不是打包生成的html):
<html lang="en"><head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
<style type="text/css">body {
    color: whitesmoke;
}</style><style type="text/css">body {
    background: black;
}</style></head>
<body>
    hello world!
<script type="text/javascript" src="main.js"></script>
</body></html>
  • 补充
    由于css样式会被插入到html文件的header末尾,所以自己在html中写的样式会被覆盖,如果想要应用上自己写的样式,就然css样式插入到最前面:
module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                	// 对象语法
                    {
                        loader: "style-loader",
                        options: {
                            // 插入到顶部
                            insertAt: "top"
                        }
                    },
                    "css-loader"
                ]
            }
        ]
   }
2.5.2 配置使用less
  • 修改index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style type="text/css">
        body {
            background: deeppink;
        }
    </style>
</head>
<body>
    hello world!
    <div id="ls">

    </div>
</body>
</html>
  • 新建style.less文件
body {
    #ls {
        width: 100px;
        height: 100px;
        border: 2px solid white;
    }
}
  • index.js中引入style.less
import "./main.css";
// 引入 less  使用import 和 require都可以
require("./style.less")
  • 安装lessless-loader
npm install less less-loader -D
  • 配置less
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    {
                        loader: "style-loader",
                        options: {
                            // 插入到顶部
                            insertAt: "top"
                        }
                    },
                    "css-loader"
                ]
            },
            // 对less文件的配置
            {
                // 配置处理less文件
                test: /\.less$/,
                // 从后向前执行 先执行 less-loader 再执行 css-loader 最后执行 css-loader 
                use: ['style-loader', 'css-loader', 'less-loader']
            }
        ]
   }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值