美文网首页让前端飞Web前端之路
webpack4 配置(CSS、静态资源、ES6 环境、开发服务

webpack4 配置(CSS、静态资源、ES6 环境、开发服务

作者: IllIIlIlIII | 来源:发表于2019-09-28 21:58 被阅读0次

    本文会一步一步从 webpack 安装、npm 脚本命令添加、各个插件的作用和安装及配置一步一步说明,如果不想看,可以跳到文末,我会把所有安装的插件和配置汇总放在最后。

    1. 安装 webpack 和 webpack-cli

    npm install --save-dev webpack webpack-cli
    

    新建 src 目录,此为源文件目录
    因为非全局安装,webpack 没加入全局变量,只能通过npx执行命令

    npx webpack // npx为npm 5.2后增加的命令
    

    打包后会生成 dist 目录,此为打包文件的目录

    ├── /项目目录(根目录)
    │   ├──  /src(源文件目录)
    │          └── index.js
    │   ├──  /dist(打包文件生成目录)
    │          └── main.js
    │   ├──  /node_modules(包安装目录)
    │          └── ......
    │   ├──  package-lock.json
    │   └──  package.json
    

    2. 为 npm 添加命令

    使用过 vue.js 的脚手架 vue-cli 的话,会常用到命令如:

    npm run dev
    

    其实这个是 vue-cli 在 npm 中配置好的。
    package.jsonscripts 中就可以配置脚本:

      // ...
      "scripts": {
        "build": "webpack --config webpack.config.js",
      },
      //  ...
    

    上述配置会增加一个打包命令:

    npm run build
    

    3. 配置webpack

    在根目录新建 webpack.config.js 如下:

    const path = require('path')
    module.exports = {
        entry: './src/index.js', //入口文件
        output: {
            filename: 'bundle.[hash].js', //默认为main.js 
            path: path.resolve(__dirname,'./dist') //path为绝对路径,用node path模块转化
        },
        mode: 'development' //开发模式
    }
    
    • entry 为入口源文件
    • output 为打包后生成文件的设置,其中 filename 为生成的文件名,[hash]为随机哈希字符串,避免缓存。path 为打包文件生成的目录。
    • mode 为打包的模式,默认为production(生产模式),会压缩代码。development(开发模式)不会压缩代码,便于阅读。
    • tips:打包文件使用[hash]后,每次打包都会生成新的文件,久了会产生大量冗余文件,这个时候就需要用到 clean-webpack-plugin 来清除老版本文件。
    npm i clean-webpack-plugin -D // i 等于 install, -D 等于 --save-dev
    

    webpack.config.js 里引入

    // ...
    const CleanWebpackPlugin = require('clean-webpack-plugin')
    module.exports = {
        // ...
        plugins:[ //存放插件
            new CleanWebpackPlugin()
        ]
    }
    

    此时的 webpack.config.js 长这个样子:

    const path = require('path')
    const CleanWebpackPlugin = require('clean-webpack-plugin')
    module.exports = {
        entry: './src/index.js', //入口文件
        output: {
            filename: 'bundle.[hash].js', //默认为main.js  [hash]是为了避免js缓存
            path: path.resolve(__dirname,'./dist') //path为绝对路径,用node path模块转化
        },
        mode: 'development', //开发模式
        plugins:[ //存放插件
            new CleanWebpackPlugin()
        ]
    }
    

    现在,每次打包前,都会清空 dist 目录

    4. 自动生成 html

    目前打包只能生成 js 文件,每次都还要手动的去 html 文件中引用,十分不方便,如果需要自动生成 html,则要用到 html-webpack-plugin

    npm i html-webpack-plugin -D
    

    src 目录下新建模版 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>模板</title>
    </head>
    <body>
        html
    </body>
    </html>
    

    webpack.config.js 里引入

    const HtmlWebpackPlugin = require('html-webpack-plugin')
    module.exports = {
        // ...
        plugins:[
            // ...
            new HtmlWebpackPlugin({
                template: './src/index.html', // 模板位置
                filename: 'index.html', // 生成的html文件名,默认也是index.html
                minify: {
                    removeAttributeQuotes: true, // 删除标签属性的双引号
                    collapseInlineTagWhitespace: true, // 删除多余空格
                },
                hash: true  // 增加hash,避免缓存
            })
        ]
    }
    

    现在,每次打包,会在 dist 目录中生成一个 index.html,并自动引入 js 文件

    5. 配置本地开发服务器

    本地开发服务器可以不用每次都打包生成文件,再去看效果:

    npm i webpack-dev-server -D
    

    webpack.config.js 里引入

        devServer:{ // 开发服务器配置
            port: 3000, // 端口号
            progress: true, // 进度条
            contentBase: './static', // 服务默认指向文件夹,静态资源
            inline: true, // 设置为true,当源文件改变的时候会自动刷新
            historyApiFallback: true, // 在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html
            hot: true, // 允许热加载
            open: true // 自动打开浏览器
        }
    

    启动这个服务可以通过如下命令启动

    npx webpack-dev-server
    

    也可以在 package.jsonscripts 脚本配置:

      "scripts": {
        "build": "webpack --config webpack.config.js",
        "dev": "webpack-dev-server"
      }
    
    

    运行

    npm run dev
    

    则自动在浏览器打开了一个服务。
    到此,目录结构 如下:

    ├── /项目目录(根目录)
    │   ├──  /src(源文件目录)
    │          ├── index.html
    │          └── index.js
    │   ├──  /dist(打包文件生成目录)
    │          ├── index.html
    │          └── bundle.2957e949a4a4bf4735f3.js
    │   ├──  /node_modules(包安装目录)
    │          └── ......
    │   ├──  /static(静态资源目录)
    │          └── ......
    │   ├──  package-lock.json
    │   ├──  package.json
    │   └──  webpack.config.js
    

    6. css模块的配置

    引入 css 文件,一般是在 html 中通过 link 标签引入,或者在 js 中

    require('./style.css')
    

    因为 webpack 默认不识别 css、less,则需要安装各种 ** loader** :

    npm i css-loader style-loader less less-loader -D
    

    webpack.config.js 中加入 loader

    // ...
    module.exports = {
          // ...
        module: {
            rules: [ 
                {
                    test: /\.css$/, // js 中 require css
                    use: ['style-loader','css-loader']
                },
                { 
                    test: /\.less$/, 
                    // 注意顺序!
                    use: ['style-loader','css-loader','less-loader'] 
                }
            ]
        },
        plugins:[
           // 存放插件
        ],
        devServer:{
           // 开发服务器
        }
    }
    

    7. ES6 处理

    目前的浏览器对 ES6 语法支持都不完整,需要转化成 ES5 才能执行:

    npm install babel-loader @babel/core @babel/preset-env -D
    

    webpack.config.js 中加入 :

    // ...
    module.exports = {
          // ...
        module: {
            rules: [ 
                // ...
                {
                    test: /\.m?js$/,
                    exclude: /(node_modules|bower_components)/,
                    use: {
                      loader: 'babel-loader',
                      options: {
                        presets: ['@babel/preset-env']
                      }
                    }
                }
            ]
        },
        plugins:[
           // 存放插件
        ],
        devServer:{
           // 开发服务器
        }
    }
    

    es6 内置方法转化:

    npm i @babel/plugin-transform-runtime -D
    npm install --save @babel/runtime @babel/polyfill  // 这个正式环境也要用
    

    babel-runtime和babel-polyfill的作用介绍和使用
    上面的 webpack.config.js 改为 :

    // ...
    module.exports = {
          // ...
        module: {
            rules: [ 
                // ...
                {
                    test: /\.m?js$/,
                    exclude: /(node_modules|bower_components)/,
                    use: {
                      loader: 'babel-loader',
                      options: {
                        presets: ['@babel/preset-env'],
                        plugins:[ // es6 内置函数转换
                            '@babel/plugin-transform-runtime'
                        ]
                      }
                    }
                }
            ]
        },
        plugins:[
           // 存放插件
        ],
        devServer:{
           // 开发服务器
        }
    }
    

    js文件里引入:

    require('@babel/polyfill')
    

    至此,可以打包 ES6 语法的文件了。

    8. 加载图片、音频等资源

    以图片为例,引入情况有三种:

    • css 中的背景图片
    body{
        background: url('./img/bg.jpg')
    }
    
    • js中通过创建Image标签再引入:
    import logo from './img/logo.jpg'
    let img = new Image()
    img.src = logo
    
    • 在html标签中引入
    <img src="./img/logo.jpg" alt="">
    

    前两中情况,需要安装:

    npm i url-loader file-loader -D
    

    webpack.config.js 加入:

    // ...
    module.exports = {
          // ...
        module: {
            rules: [ 
                // ...
                {
                    test: /\.(png|jpe?g|gif|m4a)$/, // 加载js img 对象、css 中的图片、音频等资源
                    use: [
                        {
                            loader: 'url-loader',
                            options: {
                                //资源大小小于等于limit值,则会以base64形式加载,不会发请求,大于这个值则用file-loader加载
                                limit: 200*1024
                            }
                        }
                    ]
                }
            ]
        },
        plugins:[
           // 存放插件
        ],
        devServer:{
           // 开发服务器
        }
    }
    

    在html标签中引入图片需要安装:

    npm i html-withimg-loader -D
    

    webpack.config.js 加入:

    // ...
    module.exports = {
          // ...
        module: {
            rules: [ 
                // ...
                {
                    test: /\.html$/, // 加载 img 标签中的图片
                    use: [
                      {
                        loader: 'html-withimg-loader',
                        options: {}
                      }
                    ]
                }
            ]
        },
        plugins:[
           // 存放插件
        ],
        devServer:{
           // 开发服务器
        }
    }
    

    汇总:

    最后 webpack.config.js 长这个样子:

    const path = require('path')
    const { CleanWebpackPlugin } = require('clean-webpack-plugin') // 自动清除沉余js
    const HtmlWebpackPlugin = require('html-webpack-plugin') // 自动生成 html 插件
    
    module.exports = {
        entry: './src/index.js', //入口文件
        output: {
            filename: 'bundle.[hash].js', // 默认为main.js  [hash]是为了避免js缓存
            path: path.resolve(__dirname,'./dist') // path为绝对路径,用node path模块转化
        },
        mode: 'development', // 开发模式, 生产模式 'production' 会压缩代码
        module: { // 加载 css less
            rules: [
                {
                    test: /\.css$/, // js 中 require css
                    use: ['style-loader','css-loader']
                },
                { 
                    test: /\.less$/, 
                    // 注意顺序
                    use: ['style-loader','css-loader','less-loader'] 
                },
                {
                    test: /\.m?js$/,
                    exclude: /(node_modules|bower_components)/,
                    use: {
                      loader: 'babel-loader',
                      options: {
                        presets: ['@babel/preset-env'],
                        plugins:[ // es6 内置函数转换
                            '@babel/plugin-transform-runtime'
                        ]
                      }
                    }
                },
                {
                    test: /\.(png|jpe?g|gif|m4a)$/, // 加载js img 对象、css 中的图片、音频等资源
                    use: [
                        {
                            loader: 'url-loader',
                            options: {
                                //图片大小小于等于limit值,则会以base64形式加载,不会发请求,大于这个值则用file-loader加载
                                limit: 200*1024
                            }
                        }
                    ]
                },
                {
                    test: /\.html$/, // 加载 img 标签中的图片
                    use: [
                      {
                        loader: 'html-withimg-loader',
                        options: {}
                      }
                    ]
                }
            ]
        },
        plugins:[ // 存放插件
            new HtmlWebpackPlugin({
                template: './src/index.html', // 模板
                filename: 'index.html', // 默认也是index.html
                minify: {
                    removeAttributeQuotes: true, // 删除标签属性的双引号
                    collapseInlineTagWhitespace: true, // 删除多余空格
                },
                hash: true, // 增加hash,避免缓存
            }),
            new CleanWebpackPlugin()
        ],
        devServer:{ // 开发服务器配置
            port: 3000, // 端口号
            progress: true, // 进度条
            contentBase: './static', // 服务默认指向文件夹
            inline: true, // 设置为true,当源文件改变的时候会自动刷新
            historyApiFallback: true, // 在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html
            hot: true, // 允许热加载
            open: true // 自动打开浏览器
        }
    }
    

    最后 package.json 长这个样子(变了的只有 scripts 部分,配置脚本):

    {
      "name": "audio-player",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "build": "webpack --config webpack.config.js",
        "dev": "webpack-dev-server"
      },
      "author": "sparket",
      "license": "ISC",
      "devDependencies": {
        "@babel/core": "^7.6.0",
        "@babel/plugin-transform-runtime": "^7.6.0",
        "@babel/preset-env": "^7.6.0",
        "babel-loader": "^8.0.6",
        "clean-webpack-plugin": "^3.0.0",
        "css-loader": "^3.2.0",
        "html-webpack-plugin": "^3.2.0",
        "less": "^3.10.3",
        "less-loader": "^5.0.0",
        "style-loader": "^1.0.0",
        "webpack": "^4.40.2",
        "webpack-cli": "^3.3.9",
        "webpack-dev-server": "^3.8.1"
      },
      "dependencies": {
        "@babel/polyfill": "^7.6.0",
        "@babel/runtime": "^7.6.0",
        "file-loader": "^4.2.0",
        "html-withimg-loader": "^0.1.16",
        "url-loader": "^2.1.0"
      }
    }
    

    安装的插件有:

    npm i --D webpack webpack-cli clean-webpack-plugin html-webpack-plugin webpack-dev-server css-loader style-loader less less-loader babel-loader url-loader file-loader html-withimg-loader @babel/core @babel/preset-env @babel/plugin-transform-runtime
    
    npm i --save @babel/runtime @babel/polyfill
    

    参考资料:
    1.https://www.jianshu.com/p/99675e491ee6
    2.https://www.jianshu.com/p/f06e901860e
    3.https://www.jianshu.com/p/bacc576979fe

    相关文章

      网友评论

        本文标题:webpack4 配置(CSS、静态资源、ES6 环境、开发服务

        本文链接:https://www.haomeiwen.com/subject/obitpctx.html