Powered by md-Blog  文 - 篇  访客 -

webpack4.0安装配置构建范例一条龙


  分类:大前端  / 
更新:2020-03-22 17:13:20  /  创建:2020-01-20 14:53:20
不要删除

1、为何需要类似 webpack 的构建工具?

  • 转换 ES6 语法
  • 转换 JSX 扩展语法
  • CSS 前缀补全 / 预处理
  • 压缩混淆
  • 图片压缩

2、webpack 配置文件

可以通过 webpack --config 指定配置文件

默认: webpack.config.js
module.exports = {
    entry: './src/index.js', // 入口文件
    output: './dist/main.js',   // 输出
    mode: 'production',     // 环境
    module:{
        rules:[     // Loader 配置
            {test:/\.txt$/,use:'raw-loader'}
        ]
    },
    plugins:[      // 插件配置
        new HtmlwebpackPlugin({
            template: './src/index.html'
        })
    ]
};

3、安装环境

安装 NVM

nvm是让你在同一台机器上安装和切换不同版本的node的工具

github:https://github.com/nvm-sh/nvm
提供两种方式的安装

curl 安装:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash

wget 安装:

wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash

命令:

nvm ls-remote:列出所有可以安装的node版本号
nvm install v10.15.3:安装指定版本号的node
nvm use v10.3.0:切换node的版本,这个是全局的
nvm current:当前node版本
nvm ls:列出所有已经安装的node版本

安装 Node.js 和 NPM

nvm 列出可安装的版本:

nvm ls-remote

找到最新的长期支持版本:v12.14.1 (Latest LTS: Erbium) 截止发稿日

安装:

nvm install v12.14.1

验证:显示版本号即为正确安装

node -v
npm -v

安装 webpackwebpack-cli

创建项目:

mkdir wp-demo

进入项目目录:

cd wp-demo

初始化 npm

npm init -y

安装 webpackwebpack-cli

npm install webpack webpack-cli --save-dev

验证:显示版本号即为正确安装

./node_modules/.bin/webpack -v

4、配置

在项目文件夹创建以下文件

./webpack.config.js
'use strict';

const path = require('path');

module.exports = {
    entry: './src/index.js',
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js'
    },
    mode: 'production'
};
./src/index.js
import { helloworld } from './helloworld'

document.write(helloworld());
./src/helloworld.js
export function helloworld() {
    return 'Hello webpack';
}

5、打包

./node_modules/.bin/webpack

上面命令有点麻烦,修改 package.json 加入一个npm 脚本命令:

{
  "name": "wp-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack" // 添加此行
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^4.41.5",
    "webpack-cli": "^3.3.10"
  }
}

今后可以通过进行打包:

npm run build

至此,HelloWorld 入门完成。

6、Entry 入口文件配置

单入口配置:

module.exports = {
    entry: './src/index.js'
};

多入口配置:

module.exports = {
    entry: {
        app: './src/app.js',
        adminApp: './src/adminApp.js'
    }
};

7、Output 输出配置

module.exports = {
    output: {
        path: path.join(__dirname, 'dist'),
        filename: '[name].js'
    }
};

8、Loaders

默认只支持 jsjson 两种文件类型,通过 Loaders 去处理其他类型的文件。

名称描述
babel-loader转换 ES6、ES7 等JS新特性的语法
css-loader支持 .css 文件的加载和解析
less-loader将 less 文件转换成 css
ts-loader将 TS 文件转换成 css
file-loader进行图片、字体的打包
raw-loader将文字以字符串形式导入
thread-loader多线程打包 js 和 css

用法:

module:{
    rules:[
        {test:/\.txt$/,use:'raw-loader'}
        // test 指定匹配规则
        // use 指定使用 loader 的名称
    ]
}

9、Mode

Mode 指定当前构建环境是:productiondevelopment 还是 none,默认 production

10、解析 ES6 范例

npm 安装 babel 及其 Loader

  • i = install
  • -D = --save-dev
npm i @babel/core @babel/preset-env babel-loader -D

项目根目录添加 .babelrc 文件:

{
    "presets": [
        "@babel/preset-env"
    ]
}

扩展:babel的配置文件

babel的配置文件是 .babelrc,增加:
babel Preset 视为 babel Plugin 的插件集合

{
    "presets":[
        "@babel/preset-env"  // 增加 ES6 的 babel preset 配置
    ],
    "plugins":[
        "@babel/proposal-class-properties"
    ]
}

增加 babel-loader

webpack.config.js
module:{
    rules:[
        {test:/\.js$/,use:'babel-loader'}
    ]
}

11、解析 css 范例

  • css-loader 用于加载 .css 文件,并转换成 commonjs 对象
  • style-loader 将样式通过 <style> 标签插入到 head

npm 安装 style-loader、css-loader

npm i style-loader css-loader -D

新建 ./search.css 文件并从 .js 文件引入

./src/search.js
import './search.css';
webpack.config.js
module:{
    rules:[
        {test:/\.js$/,use:'babel-loader'},  // 上面的 ES6
        {
            test:/\.css$/,
            use:[
                'style-loader',
                'css-loader'
            ]
        },  // 在 style 解析之上
    ]
}

12、解析 less 范例

npm 安装 less、less-loader

npm i less less-loader -D

新建 ./search.less 文件并从 .js 文件引入

./src/search.js
import './search.less';
webpack.config.js
module:{
    rules:[
        {test:/\.js$/,use:'babel-loader'},  // 上面的 ES6
        {test:/\.less$/,use:'style-loader','css-loader','less-loader'},  // 在 style、css 解析之上
    ]
}

13、解析图片、字体

npm 安装 file-loader

npm i file-loader -D

解析图片

webpack.config.js
module:{
    rules:[
        {test:/\.(png|svg|jpg|gif)$/,use:'file-loader'},
    ]
}
./src/search.js
import logo from './images/logo.png'
...
<img src={ logo }>

解析字体

webpack.config.js
module:{
    rules:[
        {test:/\.(woff|woff2|eot|ttf|otf)$/,use:'file-loader'},
    ]
}
./src/base.css
@font-face{
    font-family: 'weiruanyahei';
    src: url('./images/weruanyahei.ttf')
}

扩展 url-loader

url-loader 也可以处理图片和字体,此外可以设置较小资源自动 base64 图片转换

webpack.config.js
module:{
    rules:[
        {
            test:/\.(woff|woff2|eot|ttf|otf)$/,
            use:[{
                loader:'url-loader',
                options:{
                    limit:10240 // 图片小于10k,自动转换为 base64
                }
            }]
        },
    ]
}

14、文件监听 watch

在发现源码变化时,自动重新构建出新的输出文件

此方法的缺点:需要手动刷新浏览器、文件放在硬盘 I/O 明显

两种开启方式

  • 启动 webpack 命令时,带上 --watch 参数
  • 在配置 webpack.config.js 中设置 watch:true
package.json
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "watch": "webpack --watch"
},
npm run watch

15、热更新 webpack-dev-server

简称:WDS,优点:

  • 不刷新浏览器
  • 不输出文件,而是放在内存中
  • 使用 HotmoduleReplacementPlugin 插件

npm 安装 file-loader

npm i webpack-dev-server -D
package.json
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "watch": "webpack --watch", // 上一节的 watch
    "dev": "webpack-dev-server --open" // 新增,--open 构建完成自动开启浏览器
},
webpack.config.js
const webpack = require('webpack');
module.exports = {
    ...
    mode: 'development',
    plugins: [
        new webpack.HotModuleReplacementPlugin()
    ],
    devServer: {
        contentBase: './dist',  // 设置目录
        hot: true   // 开启热更新
    }
    ...
};

16、文件指纹

打包后输出的文件名的后缀
<script src="//abc.com/css/index_2343481ys.js?_bid=152">

文件指纹如何生成?

  • Hash:和整个项目的构建有关,只要项目文件有修改,整个项目构建的 Hash值 就会更改
  • Chunkhash:和 webpack 打包的 chunk 有关,不同的 entry 会生成不同的 Chunkhash值
  • Contenthash:根据文件内容来定义 Hash,文件内容不变,则 Contenthash值 不变

npm 安装 mini-css-extract-plugin

npm i mini-css-extract-plugin -D
webpack.prod.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    rules:[
        // 图片的文件指纹
        {
            test:/\.(png|svg|jpg|gif)$/,
            use:[{
                loader: 'file-loader',
                options:{
                    name: 'img/[name][hash:8].[ext]'
                }
            }]
        },
    ],
    output:{
        // 设置 js 的文件指纹
        filename:'[name][chunkhash:8].js',
        path:__dirname + '/dist'
    },
    plugins:[
        // 设置 css 的文件指纹
        new MiniCssExtractPlugin({
            filename: '[name][contenthash:8].css'
        })
    ]
}

17、代码压缩

js 压缩

内置了 uglifyjs-webpack-plugin,默认 production模式 自动压缩

css 压缩、html 文件压缩

使用 optimize-css-assets-webpack-plugin,同时使用 cssnano

npm 安装压缩插件

npm i optimize-css-assets-webpack-plugin -D
npm i cssnano -D
npm i html-webpack-plugin -D
webpack.prod.js
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    plugins: [
        // css 压缩
        new OptimizeCSSAssetsPlugin({
            assetNameRegExp: /\.css$/g,
            cssProcessor: require('cssnano')
        }),
        // HTML 压缩
        new HtmlWebpackPlugin({
            template: path.join(__dirname, 'src/index.html'),
            filename: 'index.html',
            chunks: ['index'],
            inject: true,
            minify: {
                html5: true,
                collapseWhitespace: true,
                preserveLineBreaks: false,
                minifyCSS: true,
                minifyJS: true,
                removeComments: false
            }
        }),
    ]
}

18、自动清理构建目录dist

插件:clean-webpack-plugin
npm i clean-webpack-plugin -D
webpack.prod.js 和 webpack.dev.js
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

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

19、自动添加CSS3前缀

插件:autoprefixer
npm i postcss-loader autoprefixer -D
{
    test: /\.(sc|c|sa)ss$/,
    use: [
        MiniCssExtractPlugin.loader,
        'css-loader',
        {
            loader: 'postcss-loader',
            options: {
                plugins: () => [
                    require('autoprefixer')({
                        overrideBrowserslist:['last 2 version', '>1%', 'ios 7']
                    })
                ]
            }
        }
    ],
    include: /src/,
},

20、CSS 移动端 px 自动转 rem

<!-- > 插件 px2rem-loader -->

暂无

<!-- `bash
npm i px2rem-loader -D


lib-flexible 库,现已停止

npm i lib-flexible -S

'css-loader',
{

loader: 'px2rem-loader',
options: {
    remUnit: 75, 
    remPrecision: 8
}

}

加入下一章节的资源内联

# 21、资源内联

> 插件:raw-loader@0.5.1

npm i raw-loader@0.5.1 -D

上一章节 `index.html` 加入下面代码块:

<head>

${ require('raw-loader!./meta.html') }
<title>index</title>
<script>${ require('raw-loader!babel-loader!../../node_modules/lib-flexible/flexible.js') }</script>

</head>


# 22、source map

>webpack.prod.js

plugins:[

...

],
devtool: 'source-map' // 添加


# 23、Tree Shaking

> 打包后剔除掉没用到的代码。

- WebPack 4.0无需配置
- mode: production 下默认开启
- 依赖 ES6 语法

# 24、Scope Hoisting

> Scope Hoisting 可以让 Webpack 打包出来的代码文件更小、运行的更快,减少函数声明代码和内存开销。

- WebPack 4.0无需配置
- mode: production 下默认开启

不要删除

小站不易,感谢支持!