【打包工具】webpack-2

191 阅读2分钟

webpack-1回顾

webpack-1中,我们做了以下事情:

  • 使用了webpack打包了js文件
  • 使用html插件打包了html
  • 使用css插件打包css
  • 使用css loader打包css
  • 使用webpack server搭建开发环境
  • 部署开发环境与生产环境
  • 配置package.json文件

我们做一下简单的总结:

1、webpack天生支持js文件,能识别js文件快速打包

2、使用html插件会自动生成一个html文件,或者使用模板文件来生成以源代码为基础的html文件。所以我们只需要提供0-1的html文件就可以webpack打包

3、使用css loader模式来打包css,最终会以js文件的形式新增style标签到html文件中

4、使用css插件会生成css文件的形式link到html中

5、我们可以通过浏览器缓存的特性来搭建生产环境,并且让webpack帮我们hash文件名

6、webpack server提供我们开发支持,虽然官方文档中说会以dist目录里的文件做server,但是实际上删除生成的dist目录也不影响效果,说明webpack内部隐式做了处理,并不是以生成的dist目录为准。所以我们可以通过这个功能来搭建开发环境

7、webpack的配置真的是一件麻烦的事情啊~

loader与plugin的区别

1、loader是加载器,plugin是插件

2、loader用来load一个文件,以css loade为例,它能够(通过js的方式)将css load成style,所以我们需要在配置中的use项写style loadercss loader

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [ 'style-loader', 'css-loader' ] //写了两个
      }
    ]
  }
}

而plugin是用来增强webpack功能的,它能够生成插件支持的格式文件,所以我们可以发现,只要我们importcss,最终会生成一份css文件,并且让你的index.html自动link到它。html webpack plugin则会生成一份html文件

打包scss文件

按照上面的套路,我们已经知道了,我们可以使用loader或者plugin来打包scss文件,首先是安装

yarn add sass-loader dart-sass --dev

安装sass-loaderdart-sass

配置

    module: {
        rules: [{
            test: /\.s[ac]ss$/i,
            use: [
                'style-loader',
                'css-loader',
                {
                    loader: 'sass-loader',
                    options: {
                        implementation: require('dart-sass'),
                    },
                },
            ],
        }]
    }

打包less文件

安装

yarn add less less-loader --dev

配置

	{
      test: /\.less$/,
      use: ['style-loader', 'css-loader', 'less-loader'] // compiles Less to CSS
     }

打包stylus

安装

yarn add stylus stylus-loader --dev

配置

module.exports = {
  module: {
    rules: [
      {
       test: /\.styl/,
       use: ['style-loader', 'css-loader', 'stylus-loader']
      },
    ],
  },
};

打包图片

安装

yarn add file-loader --dev

配置

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif)$/i,
        use: [
          {
            loader: 'file-loader',
          },
        ],
      },
    ],
  },
};

使用

import png from './file/1.png' //引入后可以当成变量使用
document.querySelector('.app').innerHTML = `<img src=${png}></img>`

懒加载

懒加载或者按需加载,是一种很好的优化网页或应用的方式。

如果说我们的js文件体积很大,或者一开始就不需要加载,那么当用户打开时,我们可以设置某个事件情况下才加载js文件。

以click事件为例,我们来模拟一下懒加载

步骤

  • 准备一个懒加载
  • 新建一个js文件,内容如下:
    function fn() {
        console.log('懒加载')
    }
    export default fn
  • index.js文件中设置button的点击事件
document.querySelector('button').onclick = () => {
    const p = import('./lazy.js') //此时p是promise对象
    console.log(p) //打出来看看
    p.then((module) => { //成功后promiseResult会返回一个module,通过内部的default属性可以获得export出来的函数
        module.default()
    }, () => {
        console.log('失败后的代码')
    })
}

通过import函数后的promise返回结果,Module

结论

webpack通过import函数返回一个promise,成功后这个promise会带着Module结果,我们只需要在then里做处理即可实现懒加载,参数就是Module

代码分离

我在提交github前yarn build了一下,发现我tm没有给production环境配webpack的loader,这就很烦了,我还得再写一遍到production环境的config,js里面吗?

然后我大概花了三个小时,找方法一小时,抄文档半小时,剩下一个半小时在看为什么不行。

终于让我试完了,我将在这里写下我踩的坑

方法主要是需要建立common文件,然后使用插件让他们合并关联

安装插件

yarn add webpack-merge --dev

这个插件可以帮助我们关联config文件

准备config文件

准备三份config文件,分别是common(放公共样式)、dev(开发环境)、prod(生产环境)

我的命名

 |- webpack.common.js
 |- webpack.dev.js
 |- webpack.prod.js

config文件设置

common.js中丢入公共的打包配置即可。以我的为例

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); 
module.exports = {
    entry: './src/index.js',
    output: {
        filename: '[name].[contenthash].js',
        path: path.resolve(__dirname, 'dist')
    },
    plugins: [
        new HtmlWebpackPlugin({
            title: 'qiuyanxi',
            template: 'src/index.html'
        }),
    ];

common的里面丢一些公共配置,例如less啊,png啊之类的配置

dev.js里面丢开发者环境,以我的为例

const {
    merge
} = require('webpack-merge');
const common = require('./webpack.common.js');
//--------上面这两句一定要写 
//--------日常踩坑,这里要写merge(common,{})
module.exports = merge(common, { 
    mode: `development`, 
    devtool: 'inline-source-map',
    devServer: {
        contentBase: './dist',
    },
    module: {
        rules: [{
            test: /\.css$/,
            use: ['style-loader', 'css-loader']
        }]
    }
})

请注意我的注释

prod里面丢生产环境,以我的为例

const {
    merge
} = require('webpack-merge');
const common = require('./webpack.common.js');
//---------------------上面这两句一定要写
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 
//---------日常踩坑,这里要写merge(common,{})
module.exports = merge(common, {
    mode: `production`, 
    plugins: [
        new MiniCssExtractPlugin({
            filename: '[name].[contenthash].css',
            chunkFilename: '[id].[contenthash].css',
            ignoreOrder: false, 
        }),
    ],
    module: {
        rules: [{
            test: /\.css$/,
            use: [{
                    loader: MiniCssExtractPlugin.loader,
                    options: {
                        publicPath: '../',
                        // hmr: process.env.NODE_ENV === 'development',
                    },
                },
                'css-loader',
            ],
        }, ],
    },
});

说明

上面的代码中,我只是把css loaderMINI-css plugin做了区分,其他都基本在公共文件common.js

配置package.json

  "scripts": {
    "build": "rm -rf dist && npx webpack --config webpack.prod.js",
    "start": "webpack-dev-server --open --config webpack.dev.js"
  },

最后吐槽

webpack真香,配置真烦,官方文档学习成本真的高,害我今天坐一天了就搞这些玩意。

参考文档

代码分离:webpack.js.org/guides/prod…

懒加载:www.webpackjs.com/guides/lazy…

github地址

github.com/18888628835…