webpack由浅入深——(webpack基础配置)

webpack的作用

构建就是把源代码转换成发布到线上的可执行JavaScrip、CSS、HTML代码,包括如下内容:

  • 代码校验:在代码被提交到仓库前需要校验代码是否符合规范,以及单元测试是否通过。
  • 代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等。
  • 模块合并:在采用模块化的项目里会有很多个模块和文件,需要构建功能把模块分类合并成一个文件。
  • 代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载。
  • 文件优化:压缩 JavaScript、CSS、HTML 代码,压缩合并图片等。
  • 自动刷新:监听本地源代码的变化,自动重新构建、刷新浏览器。
  • 自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。

webapck核心概念

  • Entry:入口,Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。
  • Output:输出结果,在Webpack经过一系列处理并得出最终想要的代码后输出结果。
  • Module:模块,在 Webpack里一切皆模块,一个模块对应着一个文件。Webpack会从配置的 Entry 开始递归找出所有依赖的模块。
  • Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。
  • Loader:模块转换器,用于把模块原内容按照需求转换成新内容。
  • Plugin:扩展插件,在Webpack构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要的事情。

webpack工作过程

  1. Webpack 启动后会从Entry里配置的Module开始递归解析 Entry 依赖的所有 Module。
  2. 每找到一个 Module, 就会根据配置的Loader去找出对应的转换规则,对Module 进行转换后,再解析出当前 Module 依赖的 Module。 这些模块会以 Entry 为单位进行分组,一个 Entry 和其所有依赖的 Module 被分到一个组也就是一个 Chunk。
  3. 最后 Webpack 会把所有 Chunk 转换成文件输出。 在整个流程中 Webpack 会在恰当的时机执行Plugin 里定义的逻辑。

webpack系列文章

  1. webpack由浅入深——(webpack基础配置)
  2. webpack由浅入深——(webpack优化配置)
  3. webpack由浅入深——(tapable)
  4. webpack由浅入深——(ast)
  5. webpack由浅入深——(webapck简易版)
  6. webpack由浅入深——(loader实现)
  7. webpack由浅入深——(plugin实现)

初始化项目

首先确保电脑已经安装了nodejs,推荐采用nvm的形式进行安装,这样就不用配置环境变量或者创建软链接。

mkdir webpack-learn //通过命令行创建文件夹
cd webpack-learn    //打开创建的文件夹
npm init -y //初始化一个项目
npm install webpack webpack-cli -D //本地安装webpack和webpack-cli
mkdir src   //创建src目录来存放源代码
mkdir dist  //创建dist目录来存放打包后的代码
复制代码

在src目录下创建index.js

let str = require('./a');
console.log(str);
复制代码

在src目录下创建a.js

module.exports='webpack-learn'
复制代码

在dist目录下创建index.html文件




    
    
    
    Document


复制代码

利用webpack进行打包,关于commonjs不清楚的,请参考require()源码解读

npx webpack -- mode development //以默认以开发模式进行打包
复制代码

[图片上传中...(image-d122a4-1540439603940-4)]

Entry(入口)和Output(输出)

从上面的代码中可以看到文件打包到了dist/main.js中,所以需要进行相应的配置webpack.config.js来自定义结果文件名。

单入口

  • 字符串形式
const path=require('path');
module.exports={
    entry: './src/index.js',    //入口
    output: {
        path: path.resolve(__dirname,'dist'),   //出口,绝对路径
        filename:'bundle.js'
    },
    module: {},     //配置loader
    plugins: [],    //配置插件
    devServer: {}   //配置本地服务
    resolve:{},     //配置解析文件路径等
}
复制代码
  • 数组形式
//index.js
console.log('hello');
复制代码
//a.js
console.log('world')
复制代码
const path=require('path');
module.exports={
    //index和a之间没有依赖关系,只是单纯的合并
    entry: ['./src/index.js','./src/a.js'],
    output: {
        path: path.resolve(__dirname,'dist'),  
        filename:'bundle.js'
    },
    module: {},     
    plugins: [],    
    devServer: {}   
    resolve:{},
}
复制代码

多入口

//a.js
let str =require('./c')
console.log(str);
复制代码
//b.js
let str =require('./d')
console.log(str);
复制代码
//c.js
module.export = 'hello'
复制代码
//d.js
module.export = 'world'
复制代码
const path=require('path');
module.exports={
    //多入口拆分功能,可以两个页面分别引用一个,也可以一个页面引用多个
    //配合后面的html-webpack-plugin使用
    entry: {
        pageA:'./src/a',
        pageB:'./src/b'
    },
    output: {
        path: path.resolve(__dirname,'dist'), 
        //带有哈希值的文件名exp:pageA.fa112c62、pageB.fa112c62
        filename:'[name].[hash:8].js'    
    },
    module: {},     
    plugins: [],    
    devServer: {}   
    resolve:{},
}
复制代码

自动生成页面

现在页面是手动创建到dist目录下的,一个页面还好,如果存在多个页面,手动创造html的代价是很大的,可以利用html-webpack-plugin来自动创建页面:

npm install html-webpack-plugin -D
复制代码
//src/index.html



    
    
    
    Document




复制代码
const path = require('path');
const webpack =require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    entry:{
        pageA:'./src/a',
        pageB:'./src/b'
    },
    output: {
        path: path.resolve(__dirname,'dist'), 
        filename:'[name].[hash:8].js'    
    },
    module: {},
    plugins: [
        //在实际项目中,通过读取需要创建的页面信息,遍历创建实例
         new HtmlWebpackPlugin({
            template:'./src/index.html',
            filename:'pageA.html',
            chunks:['pageA,pageB'],   //数组,可以放多个chunk
            //页面资源携带哈希值exp:pageA.fa112c62?r2452567&4124
            //中间哈希一直都有,这个后面的哈希只在页面引用添加在页面中
            hash:true,  
            minify:{
                collapseWhitespace:true, //压缩代码,去除空格和换行
                removeAttributeQuotes:true//压缩代码,去除属性双引号    
            }
        }),
        new HtmlWebpackPlugin({
            template:'./src/index.html',
            filename:'pageB.html',
            chunks:['pageB'],
            hash:true,
            minify:{
                collapseWhitespace:true,
                removeAttributeQuotes:true
            }
        })
    ],
    devServer: {},
    resolve:{},
}
复制代码

配置script

由于每次打包都需要执行npx webpack --mode development,所以可以在package.json中进行配置:

"scripts": {
    //等价于webpack --config webpack.config.js --mode development
    //默认是执行webpack.config.js,可以根据env来配置执行不同的文件
    "start": "webpack --mode development"
  },
复制代码

devServer(本地服务器)

首先必须的安装插件webpack-dev-derver:

npm install webpack-dev-server -D   
复制代码

修改script:

"scripts": {
    "dev":"webpack-dev-server --mode development"
    "build": "webpack --mode development"
 },
复制代码

修改配置文件:

//index.html



    
    
    
    Document


    
复制代码
//a.js
module.exports = 'hello'
复制代码
//index.js
let str = require('./a');
document.getElementById('app').innerHTML = str;
复制代码
const path=require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports={
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname,'dist'), 
        filename:'bundle.js'
    },
    module: {}, 
    plugins: [
         new HtmlWebpackPlugin({
            template:'./src/index.html',
            filename:'index.html',
            hash:true,
            minify:{
                collapseWhitespace:true,
                removeAttributeQuotes:true
            }
        })
    ],
    devServer: {
        //devServer会在打包的时候把生成的文件放在内存中,
        //并且是以根目录为参照目录而不是dist目录,所以需要修改
        contentBase:'./dist',
        port:'3000',
    } 
    resolve:{},
}
复制代码

通过浏览器,输入localhost:3000就可以看到

[图片上传中...(image-18105c-1540439603940-3)]

通过修改a.js中module.exports = 'hello1',可以看到

[图片上传中...(image-f88b0-1540439603940-2)]

这样会有一个问题,就是只要源代码中存在改动,就会刷新页面。假如在react本地开发的时候,有很多组件,其中一个组件的代码修改了,不希望所有的组件都更新,可以利用热更新来解决:

const path = require('path');
const webpack =require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports={
    entry:'./src/index.js',
    output: {
        filename:'bundle.js',
        path: path.resolve(__dirname,'dist')
    },
    module: {},
    plugins: [
        //使用热更新插件
        new webpack.HotModuleReplacementPlugin();
        new HtmlWebpackPlugin({
            template:'./src/index.html',
            filename:'index.html',
            hash:true,
            minify:{
                collapseWhitespace:true,
                removeAttributeQuotes:true
            }
        })
    ],
    devServer: {    
        contentBase:'./dist',
        port:'3000',
        hot:true    //热更新开关,使用websocket来通知页面更新
    },
    resolve:{},
}
复制代码
//index.js
let str = require('./a');
document.getElementById('app').innerHTML = str;

//这里必须加这段,不然的话,还是没有办法使用热更新
if(module.hot){
    module.hot.accept();
}
复制代码

module中的loader

webpack每找到一个Module,就会根据配置的Loader去找出对应的转换规则,让js能过编译css、ejs、jsx和图片的各种格式。

css相关loader

  • style-loader 和css-loader
//index.css
body{
    background:red;
    border-radio:4px;
}
复制代码
//一般前端代码使用import引入模块,node服务使用require引入模块
import str from './a'
import './index.css'
document.getElementById('app').innerHTML=str

if(module.hot){
    module.hot.accept();
}
复制代码

执行npm run build之后发现出现以下报错,说明需要配置loader:

[图片上传中...(image-f45890-1540439603939-1)]

首先需要安装loader

npm install css-loader style-loader -D
复制代码
const path = require('path');
const webpack =require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    entry:{
        index:'./src/index'
    },
    output: {
        filename:'[name].[hash:8].js',
        path: path.resolve(__dirname,'dist')
    },
    module: {
        rules:[
            {
                test:/\.css$/,
                //多个loaders用数组,loader的形式有字符串和对象两种
                //字符串形式:'xxx?option1!yyyy'
                //对象形式{loader:'xxx',options:{option1:yyyy}}
                //less-laoder将less转化为css,css-loader解析css,style-loader插入到style标签中
                use:['style-oader','css-loader']    
            }
        ]
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new HtmlWebpackPlugin({
            template:'./src/index.html',
            filename:'index.html',
            chunks:['index']
        })
    ],
    devServer: {    
        contentBase:'./dist',
        port:'3000',
        hot:true
    },
    resolve:{},
}
复制代码

用npm run dev启动服务可以看到效果,但是这样有一个问题,css样式采用的内嵌式,最好能抽离出来使用外链式引入,可以使用插件mini-css-extract-plugin:

npm install mini-css-extract-plugin -D
复制代码
const path = require('path');
const webpack =require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
    entry:{
        index:'./src/index'
    },
    output: {
        filename:'[name].[hash:8].js',
        path: path.resolve(__dirname,'dist')
    },
    module: {
        rules:[
            {
                test:/\.css$/,
                use:[{
                    loader:MiniCssExtractPlugin.loader,
                    options:{
                        //将css中的路经前面添加,background:url('xxxx')
                        //http://ssss/xxxxx
                        publicPath:'http://sssss'    
                    }
                },
                'css-loader'
                ]    
            }
        ]
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new MiniCssExtractPlugin({
            filename:index.css,
        }),
        new HtmlWebpackPlugin({
            template:'./src/index.html',
            filename:'index.html',
            chunks:['index']
        })
    ],
    devServer: {    
        contentBase:'./dist',
        port:'3000',
        hot:true
    },
    resolve:{},
}
复制代码
  • postcss-loader和autoprefixer插件

由于前端写的代码要兼容各种浏览器,css属性为了兼容各大浏览器,往往需要添加各种前缀,但是同一个属性写多份,这个工作量还是比较大的,有一个postcss-loader可以配合autoprefixer插件使用

//index.css
body{
    background:red;
    transform: rotate(0,0,100deg);
}
复制代码
npm install postcss-loader autoprefixer -D
复制代码
//创建postcss.config.js
module.exports ={
    plugins:[
        require('autoprefixer')
    ]
} 
复制代码
const path = require('path');
const webpack =require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
    entry:{
        index:'./src/index'
    },
    output: {
        filename:'[name].[hash:8].js',
        path: path.resolve(__dirname,'dist')
    },
    module: {
        rules:[
            {
                test:/\.css$/,
                use:[
                {loader:MiniCssExtractPlugin.loader},
                'css-loader',
                'postcss-loader'    //添加css前缀处理laoder
                ]    
            }
        ]
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new MiniCssExtractPlugin({
            filename:index.css,
        }),
        new HtmlWebpackPlugin({
            template:'./src/index.html',
            filename:'index.html',
            chunks:['index']
        })
    ],
    devServer: {    
        contentBase:'./dist',
        port:'3000',
        hot:true
    },
    resolve:{},
}
复制代码

图片相关的loader

项目中引入图片的方式有三种:

  1. 通过js引入
//index.js
import './index.css'
import jpg from './1.jpg'
let img = new Image();
img.src=jpg;
document.body.appendChild(img);
if(module.hot){
    module.hot.accept();
}
复制代码
  1. 通过css引入
//index.css
body{
    background: url('./1.jpg') no-repeat right;
}
复制代码
  1. 通过img的src属性引入
//index.html



    
    
    
    Document


    


复制代码

处理前两种引入图片的方式需要使用file-loader和url-loader,其中url-laoder内部会引用file-loader,它们的作用就是解析js和css中的图片链接然后将图片变成base64。后一种引入图片的方式需要使用html-withimg-loader。

npm install file-loader url-loader html-withimg-loader -D
复制代码
const path = require('path');
const webpack =require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
    entry:{
        index:'./src/index'
    },
    output: {
        filename:'[name].[hash:8].js',
        path: path.resolve(__dirname,'dist')
    },
    module: {
        rules:[
            {
                test:/\.css$/,
                use:[{
                    loader:MiniCssExtractPlugin.loader,
                },'css-loader']
            },
            {
                test:/\.jpg|png/,
                use:{
                    loader:'url-loader',
                    options:{
                        //大于8k的图片会打包到dist目录下,小于8k的图片会生成base64插入到引用的地方
                        //base64会使资源变大1/4,但是base64无需发送请求,资源比较小时使用base64最佳
                        limit:8*1024   
                    }
                }
            },
            {
                test:/\.html$/,
                use:'html-withimg-loader'
            }
        ]
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new MiniCssExtractPlugin({
            filename:index.css,
        }),
        new HtmlWebpackPlugin({
            template:'./src/index.html',
            filename:'index.html',
            chunks:['index']
        })
    ],
    devServer: {    
        contentBase:'./dist',
        port:'3000',
        hot:true
    },
    resolve:{},
}
复制代码

[图片上传中...(image-c44f47-1540439603939-0)]

js相关的loader

由于ES6的简洁和API扩展,有很多开发者使用ES6进行开发,但是由于浏览器的品牌和版本的不同,就出现了开发时使用ES6然后同意转化成ES5的情况。这时候就需要使用babel对ES6+的语法进行转译,关于babel的各种配置可以参考对babel-transform-runtime,babel-polyfill的一些理解。

npm install babel-core babel-loader babel-preset-env babel-preset-stage-0 babel-plugin-tranform-runtime -D
复制代码
//创建.babelrc文件
//preset中包含了一组用来转换ES6+的语法的插件,但是还不转换新的API
//如需使用新的API,例如set(),还需要使用对应的转换插件或者polyfill(填充库)
{
    presets:{
        'env',      //环境变量,根据不同浏览器环境而对应的转码
        'stage-0'   //转译ES6+(0 > 1 > 2 > 3 > 4)
    }
    plugins:{
        'tranform-runtime'
    }
}
复制代码
const path = require('path');
const webpack =require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
    entry:{
        index:'./src/index'
    },
    output: {
        filename:'[name].[hash:8].js',
        path: path.resolve(__dirname,'dist')
    },
    module: {
        rules:[
            {
                test:/\.css$/,
                use:[{
                    loader:MiniCssExtractPlugin.loader,
                },'css-loader']
            },
            {
                test:/\.jpg|png/,
                use:{
                    loader:'url-loader',
                    options:{
                        limit:8*1024   
                    }
                }
            },
            {
                test:/\.html$/,
                use:'html-withimg-loader'
            },
            {   //使用babel-loader
                test:/\.js$/,
                use:'babel-loader',
                exclude:/node_modules/  //排除编译ndoe——modules   
            }
        ]
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new MiniCssExtractPlugin({
            filename:index.css,
        }),
        new HtmlWebpackPlugin({
            template:'./src/index.html',
            filename:'index.html',
            chunks:['index']
        })
    ],
    devServer: {    
        contentBase:'./dist',
        port:'3000',
        hot:true
    },
    resolve:{},
}
复制代码

resolve解析加载

  • extensions:使用require或import引入文件时可以省略后缀
resolve:{
    extensions:['.js','.css','.vue']
},
复制代码
  • alias:别名,简化引用路径
resolve:{
    extensions:['.js','.css','.vue'],
    alias:{
        bootstrap:'bootstrap/dist/css/bootstrap.css'    //import 'bootstrap'会找对应的路径
    }
},
复制代码
  • mainFields:require和import默认通过第三方插件的package.json中main字段中的地址来引用文件,而bootstrap中main字段使用的,可以通过设置来使用备用字段
resolve:{
    extensions:['.js','.css','.vue'],
    mainFields:['style','main']     //先找style字段再找main
},
复制代码
  • modules:限制引入第三方的范围
resolve:{
    extensions:['.js','.css','.vue'],
    mainFields:['style','main'],
    modules:[path.resolve(__dirname,node_modules),modle]    //modle为自己写的插件或组件
},
复制代码
  • mianFiles:范围下的默认优先查找的文件名
resolve:{
    extensions:['.js','.css','.vue'],
    mainFields:['style','main'],
    modules:[path.resolve(__dirname,node_modules),modle],
    mianFiles:['index.js','main.js']
},

复制代码

external和第三方库的引用

以jquery为例来说说webpack引用第三方插件的几种方式:

npm install jquery 
复制代码

webpack.ProvidePlugin

const path = require('path');
const webpack =require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
    entry:{
        index:'./src/index'
    },
    output: {
        filename:'[name].[hash:8].js',
        path: path.resolve(__dirname,'dist')
    },
    module: {
        rules:[
            {
                test:/\.css$/,
                use:[{
                    loader:MiniCssExtractPlugin.loader,
                },'css-loader']
            },
            {
                test:/\.jpg|png/,
                use:{
                    loader:'url-loader',
                    options:{
                        limit:8*1024   
                    }
                }
            },
            {
                test:/\.html$/,
                use:'html-withimg-loader'
            },
            {   //使用babel-loader
                test:/\.js$/,
                use:'babel-loader',
                exclude:'/node_modules/'
            }
        ]
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new webpack.ProvidePlugin({
            "$":'jquery'    //在全局下添加$变量,不需要再次引入
        }),
        new MiniCssExtractPlugin({
            filename:index.css,
        }),
        new HtmlWebpackPlugin({
            template:'./src/index.html',
            filename:'index.html',
            chunks:['index']
        })
    ],
    devServer: {    
        contentBase:'./dist',
        port:'3000',
        hot:true
    },
    resolve:{},
}
复制代码
//index.js
console.log($)  //在全局下添加$变量,不需要再次引入import
console.log(window.$)   //undefine,不会挂载在window上
复制代码

expose-loader

npm install export-loader -D
复制代码
const path = require('path');
const webpack =require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
    entry:{
        index:'./src/index'
    },
    output: {
        filename:'[name].[hash:8].js',
        path: path.resolve(__dirname,'dist')
    },
    module: {
        rules:[
            {
                test:/\.css$/,
                use:[{
                    loader:MiniCssExtractPlugin.loader,
                },'css-loader']
            },
            {
                test:/\.jpg|png/,
                use:{
                    loader:'url-loader',
                    options:{
                        limit:8*1024   
                    }
                }
            },
            {
                test:/\.html$/,
                use:'html-withimg-loader'
            },
            {   
                test:/\.js$/,
                use:'babel-loader',
                exclude:'/node_modules/'
            },
            {   
                test:/jquery/,
                use:{
                    loader:'expose-loader', //expose-loader暴露$
                    options:{
                        $:'jquery'
                    }
                },
            }
        ]
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new MiniCssExtractPlugin({
            filename:index.css,
        }),
        new HtmlWebpackPlugin({
            template:'./src/index.html',
            filename:'index.html',
            chunks:['index']
        })
    ],
    devServer: {    
        contentBase:'./dist',
        port:'3000',
        hot:true
    },
    resolve:{},
}
复制代码
//index.js
const $ = require('jquery');
console.log($)  
console.log(window.$)   //能够挂载在window上
复制代码

external和script直接引用

const path = require('path');
const webpack =require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
    entry:{
        index:'./src/index'
    },
    output: {
        filename:'[name].[hash:8].js',
        path: path.resolve(__dirname,'dist')
    },
    module: {
        rules:[
            {
                test:/\.css$/,
                use:[{
                    loader:MiniCssExtractPlugin.loader,
                },'css-loader']
            },
            {
                test:/\.jpg|png/,
                use:{
                    loader:'url-loader',
                    options:{
                        limit:8*1024   
                    }
                }
            },
            {
                test:/\.html$/,
                use:'html-withimg-loader'
            },
            {   
                test:/\.js$/,
                use:'babel-loader',
                exclude:'/node_modules/'
            }
        ]
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new MiniCssExtractPlugin({
            filename:index.css,
        }),
        new HtmlWebpackPlugin({
            template:'./src/index.html',
            filename:'index.html',
            chunks:['index']
        })
    ],
    externals:{
        'jquery':'$'    //表明jquery是外链CDN引用
    }
    devServer: {    
        contentBase:'./dist',
        port:'3000',
        hot:true
    },
    resolve:{},
}
复制代码
//index.html



    
    
    
    Document


复制代码

代理

  • 配置proxy
 devServer: {    
        contentBase:'./dist',
        port:'3000',
        hot:true,
        proxy:{
            target:'http://xxxxx'   //代理的服务器
            pathRewirte:{
                '/xxx':'/yyy'
            }
        }
    },
复制代码
  • webpack服务集成到自己的本地服务
// 把webpack-dev-server的配置引入到自己的本地服务
const express = require('express');
const webpackDevMiddleware = require('webpack-dev-middleware');
// 引入webpack配置文件
const config = require('./webpack.config');
let app = express();

cosnt webpack = require('webpack');
let compiler = webpack(config);     //用webpack进行编译
app.use(webpackDevMiddleware(compiler)); 

app.listen(3000);
复制代码

Plugin(插件)

plugin和loader的区别在于loader只在编译module时执行,而plugin可能在webapck工作流程的各个阶段执行。

clean-webpack-plugin

清除dist目录

module.exports = {
    mode:'production',  生产环境会自动压缩   
    entry:{
        index:'./src/index'
    },
    output: {
        filename:'[name].[hash:8].js',
        path: path.resolve(__dirname,'dist')
    },
    module: {
        rules:[
            {
                test:/\.css$/,
                use:[{
                    loader:MiniCssExtractPlugin.loader,
                },'css-loader']
            },
            {
                test:/\.jpg|png/,
                use:{
                    loader:'url-loader',
                    options:{
                        limit:8*1024   
                    }
                }
            },
            {
                test:/\.html$/,
                use:'html-withimg-loader'
            },
            {   
                test:/\.js$/,
                use:'babel-loader',
                exclude:'/node_modules/'
            }
        ]
    },
    plugins: [
        new CleanWebpackPlugin(['dist/*.*']),   //清空dist目录
        new webpack.HotModuleReplacementPlugin(),
        new MiniCssExtractPlugin({
            filename:index.css,
        }),
        new HtmlWebpackPlugin({
            template:'./src/index.html',
            filename:'index.html',
            chunks:['index']
        })
    ],
    externals:{
        'jquery':'$'
    }
    devServer: {    
        contentBase:'./dist',
        port:'3000',
        hot:true
    },
    resolve:{},
}
复制代码

uglifyjs-webpack-plugin和optimize-css-assets-webpack-plugin

module.exports = {
    mode:'production',  生产环境会自动压缩   
    entry:{
        index:'./src/index'
    },
    output: {
        filename:'[name].[hash:8].js',
        path: path.resolve(__dirname,'dist')
    },
    optimization:{
        minimizer:{
            new UglifyJSPlugin({    //压缩js
                cache:true,
                parallel:ture,  //并行压缩
                sourthMap:true, //启动sourthMap
            }) ,
            new OptimizeCssAssetsPlugin()   //压缩css
        }
    },
    module: {
        rules:[
            {
                test:/\.css$/,
                use:[{
                    loader:MiniCssExtractPlugin.loader,
                },'css-loader']
            },
            {
                test:/\.jpg|png/,
                use:{
                    loader:'url-loader',
                    options:{
                        limit:8*1024   
                    }
                }
            },
            {
                test:/\.html$/,
                use:'html-withimg-loader'
            },
            {   
                test:/\.js$/,
                use:'babel-loader',
                exclude:'/node_modules/'
            }
        ]
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new MiniCssExtractPlugin({
            filename:index.css,
        }),
        new HtmlWebpackPlugin({
            template:'./src/index.html',
            filename:'index.html',
            chunks:['index']
        })
    ],
    externals:{
        'jquery':'$'
    }
    devServer: {    
        contentBase:'./dist',
        port:'3000',
        hot:true
    },
    resolve:{},
}
复制代码

常用插件

  • html-webpack-plugin: 创建html并插入script标签
  • autoprefixer: 给cssh加前缀
  • mini-css-extract-plugin: 抽离css样式link到html
  • webpack-dev-server: 启动webpack服务
  • webpack-dev-middleware:webpack服务集成到本地的服务
  • uglifyjs-webpack-plugin:压缩js
  • optimize-css-assets-webpack-plugin:压缩css
  • clean-webpack-plugin:清空目录

结语

学习webpack的过程是从官方文档开始学习的,照着敲了一遍,然后搜索相关的内容。

作者:梦想攻城狮
链接:https://juejin.im/post/5bbec0395188255c305012d1
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的:(【Webpack点滴知识,】)