webpack4-基础配置

webpack的安装

安装本地的webpackcss

yarn add webpack webpack-cli -D
复制代码

零配置执行

npx webpack         
npx webpack --mode production   // 默认为生产环境 会进行压缩打包
npx webpack --mode development
复制代码

webpack_require 至关因而webpack本身实现的一套模块化的机制html

手动配置

默认配置文件名称为 webpack.config.jsvue

module.exports = {
    mode: 'development',  // 模式 默认两种 production development
    entry: './src/index.js',  // 入口
    output: {
        filename: 'bundle.[hash:8].js',         // 出口 [hash:8]显示8位hash值
        path: path.resolve(__dirname, 'build')    // path必须是一个绝对路径 path.resolve帮咱们把相对路径解析成绝对路径
    },
}
复制代码

在webpack-cli/bin/config-yargs中能够看到有这样一行 defaultDescription: "webpack.config.js or webpackfile.js" 即配置文件名称为webpack.config.js or webpackfile.js 固然咱们也能够手动指定配置文件的名称node

npx webpack --config filename
复制代码

也能够经过在package.json中的script里配置jquery

"scripts":{
    "build": "webpack --config webpack.config.js"   //  webpack.config.js可改成自定义文件名
},
复制代码
npm run build
复制代码

若是必定要手动传参也能够经过多加两个-webpack

"scripts":{
    "build": "webpack"   //  webpack.config.js可改成自定义文件名
},
复制代码
npm run build -- --config webpack.config.js
复制代码

到目前为止,咱们的配置依然很弱,只能打包js文件,接下来咱们继续添加更多的配置es6

下面咱们但愿可以经过http://localhost 这样的方式来启动一个服务, 咱们能够经过webpack内置的一个服务 webpack-dev-server (内部是经过express实现的)web

yarn add webpack-dev-server -D
复制代码

如今咱们能够经过express

npx webpack-dev-server
复制代码

固然也一样能够经过package.json设置npm

"scripts": {
        "dev": "webpack-dev-server",
        "build": "webpack --config webpack.config.js"
    },
复制代码

而后执行

npm run dev
复制代码

同时咱们能够给在webpack.config.js中对webpack-dev-server进行配置

devServer: {    // 开发服务器的配置
        port: '3000',
        progress: true,
        contentBase: './build',    
        open: true
    },
复制代码

html插件

指望:动态生成build/index.html, 并把打包后的文件引入到index.html

在src目录下建index.html,这时咱们须要使用插件HtmlWebpackPlugin,plugin的用法大都相同,HtmlWebpackPlugin是一个类,new一下就能够了

plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html',     // template文件
            filename: 'index.html',            // 生成的template文件名称 默认为index.html
            hash: true,                       // 在生成的html中添加引用hash
            minify: {
                removeAttributeQuotes: true,  // 去除双引号
                collapseWhitespace: true,     // 去除空行
            }
        }),
    ],
复制代码

到这里能够看到咱们既能够经过在配置output的时候经过filename: bundle.[hash:8].js 来给生成文件添加hash,也能够经过HtmlWebpackPlugin的配置hash来实现,二者添加hash的方式分别为 bundle.12345678.js和 bundle?12345678

而经过filename: bundle.[hash:8].js这种方式实现,咱们还须要再作一步,就是在每次从新打包的时候把旧的文件删除 // todo

样式处理

咱们知道,webpack默认只支持js模块,那么咱们怎么处理css/less/scss等模块呢?这时候就须要loader上场了

You may need an appropriate loader to handle this file type.
复制代码
module: {           // 模块
        rules: [    // 规则
            // css-loader 主要用来解析@import这种语法 
            // style-loader 把样式插入页面
            // loader特色,功能单一 多个loader能够协做
            // 一个loader可使用字符串,多个可使用数组, 须要传入参数时可使用对象方式
            // loader的顺序,默认为从右向左, 从下到上执行 webpack选择了compose方式
            // { 
            // test: '/\.css$/', use: [
            // { loader: 'css-loader', options: {} } // 对象方式
            // ]
            // },
            { test: /\.css$/, use: ['style-loader', 'css-loader'] },
        ]
    },
复制代码

less、sass文件同理, 以scss文件为例:

{
    test: /\.css$/, use: [
        { loader: 'style-loader', options: { insertAt: 'top' } },        // 对象方式 insertAt插入位置
        { loader: 'css-loader', options: {} },
    ]
},
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] },
复制代码

css抽离

webpack4中,css抽离须要插件 mini-css-extract-plugin (注意再也不是extract-text-webpack-plugin)

new miniCssExtractPlugin({
    filename: 'main.css',   // 抽离出的css的文件名
}),
复制代码

同时在module.rules中作以下修改以免重复插入:

- // { test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] },
+ { test: /\.scss$/, use: [miniCssExtractPlugin.loader, 'css-loader', 'sass-loader'] },
复制代码

自动添加前缀

咱们可使用postcss-loader autoprefixer来实现

- // { test: /\.scss$/, use: [miniCssExtractPlugin.loader, 'css-loader', 'sass-loader'] },

+ { test: /\.scss$/, use: [miniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader'] },
复制代码

在根目录下新建postcss.config.js

module.exports = {
    plugins: [
        require('autoprefixer'),    // 自动添加前缀
    ]
}
复制代码

压缩

此时咱们设置mode为production,发现js和html都已是压缩过的了,但是css文件却没有。咱们这里引入另一个插件:optimize-css-assets-webpack-plugin来优化css资源

let OptimizeCss = require('optimize-css-assets-webpack-plugin');
plugins: [       
        ...,                        
        new OptimizeCss(),
]
复制代码

固然咱们也能够经过uglifyjs-webpack-plugin来压缩咱们的js文件

let UglifyjsPlugin = require('uglifyjs-webpack-plugin');
plugins: [       
        ...,                        
        new UglifyjsPlugin(),
]
复制代码

es6

咱们但愿打包后的文件能够把es6语法转为es5,能够经过babel-loader帮咱们实现

// src/a.js
console.log('this is a');

const fn = () => {
    console.log('fn');
}
复制代码

安装babel依赖模块

yarn add babel-loader @babel/core @babel/preset-env -D
复制代码
{
    test: /\.js|jsx$/, use:
    {
        loader: 'babel-loader', options: {
            presets: ['@babel/preset-env']
        }
    }
},
复制代码

es7

如今写es6的语法没有问题了,可是咱们有可能用到es7的语法, 好比类的写法,这时候咱们还须要借助一个插件:@babel/plugin-proposal-class-properties 又好比装饰器的写法,咱们能够借助@babel/plugin-proposal-decorators来实现

{
    test: /\.js|jsx$/, use:
    {
        loader: 'babel-loader', options: {
            presets: ['@babel/preset-env'],
            plugins: [
                ["@babel/plugin-proposal-decorators", { "legacy": true }],  // 支持es7的装饰器的写法 要放在前面
                '@babel/plugin-proposal-class-properties',       // 支持es7的类的写法 
            ]
        }
    }
},
复制代码

这里须要注意的是@babel/plugin-proposal-decorators要放在@babel/plugin-proposal-class-properties前面。

es6新的API

babel只会帮咱们把es6新的语法转成es5,可是对于新的API如:promise, generater 等咱们还须要借助一个包 @babel-polyfill(可是比较大) 同时咱们能够借助一个插件--@babel/plugin-transform-runtime 作了必定优化,如代码抽离

js语法校验 eslint

yarn add eslint eslint-loader
复制代码
{
    test: /\.js|jsx$/,
    use: {
        loader: 'eslint-loader',
        options: {
            enforce: 'pre', // pre post 
        }
    }
},
复制代码

接下来就可使用本身配置好的.eslintrc.json文件(放在根目录下),固然咱们也能够到eslint官网,手动进行配置,而后下载eslintrc.json,只要加个.就好了。

全局变量的引入

  1. 简单粗暴
import $ from 'jquery';
    console.log($)  
    console.log(window.$) // undefined
复制代码
  1. 内联loader expose-loader 暴露到全局的loader,用法以下:
import $ from 'expose-loader?$!jquery';
console.log($)  
console.log(window.$) // undefined
复制代码
  1. webpack expose-loader 只能经过window访问
{
    test: require.resolve('jquery'),
    use: 'expose-loader?$'
},

// index.js
console.log(window.$)  
复制代码
  1. webpack内置插件
let webpack = require('webpack');

new webpack.ProvidePlugin({     // 在每一个模块中都注入$
    $: 'jquery',
}),

// index.js
console.log($);         // 均可以访问
console.log(window.$)  
复制代码
  1. cdn引入+webpack
externals: {    // 外部引入,不须要打包
    jquery: '$',
},

// index.js
import $ from 'jquery';     // 虽然引入可是不会再打包
console.log($);
复制代码

图片处理

咱们使用图片的场景有两种:

  1. 在js中建立图片来引用
  2. 再css中使用,background
  3. img标签的使用
// index.js
let img = new Image();
img.src = require('./logo.png');
document.body.appendChild(img);
复制代码

这时咱们须要借助 file-loader 了

{
    test: /\.png|jpg|gif|jpeg$/,
    loader: 'file-loader',
    options: {

    }
},
复制代码
// index.js
import logo from './logo.png';  // 返回一个新的文件 好处是能够重命名图片

let img = new Image();
img.src = logo;
document.body.appendChild(img);

// a.css
body{
    color: yellow;
    background: url('./logo.png') no-repeat;
}

复制代码

ok,发现前两种都没有什么问题,但是第三种直接写在html中的却不行

<body>
    <img src='./logo.png' alt=""/>
    <!-- 模版 -->
</body>
复制代码

处理直接写在html里的图片,还须要用到另外一个loader:

{
    test: /\.html/,
    use: 'html-withimg-loader'
},
复制代码

从新启动就行了。

文件打包分类

若是想要作更多的限制呢,好比说对打包图片大小的限制打包成base64以减小http请求(base64会比源文件大1/3左右),咱们可使用 url-loader

{
    test: /\.png|jpg|gif|jpeg$/,
    loader: 'url-loader',
    options: {
        limit: 4 * 1024,        // 图片大小限制值
        outputPath: '/img/',     // 输出目录
        publicPath: 'http://58.com'     // 添加打包后的图片域名
    }
},
复制代码

打包多页面应用

基本配置以下:

let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: {
        home: './src/index.js',
        other: './src/other.js',
    },
    output: {
        filename: '[name].js',               // name为变量,根据entry的命名生成对应打包后的文件名称
        path: path.resolve(__dirname, 'dist'),
    },
    plugins: [
        new HtmlWebpackPlugin({             // 这里须要new多个HtmlWebpackPlugin
            template: './src/index.html',
            filename: 'home.html',
            chunks: ['home']                // html依赖,决定了打包后的哪些文件插入该模版中, 能够写多个,且有顺序
        }),
        new HtmlWebpackPlugin({
            template: './src/index.html',
            filename: 'other.html',
            chunks: ['other', 'home']
        }),
    ],
}
复制代码

配置source-map

// devtool: 'source-map', // 增长映射文件 会单独生成一个sourcemap文件,出错了会标示当前出错的列和行 特色 大 全
    devtool: 'eval-map',
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html',
            filename: 'home.html',
        }),
    ],
复制代码

watch用法

output: {
        filename: '[name].js',               // name为变量,根据entry的命名生成对应打包后的文件名称
        path: path.resolve(__dirname, 'dist'),
    },
    watch: true,    // 实时编译打包
    watchOptions: { // 监控选项
        poll: 1000, // 每秒访问多少次
        aggregateTimeout: 500, // 防抖
        ignored: /node_modules/
    },
复制代码

插件使用

  • CleanWebpackPlugin 每次打包删除dist
  • CopyWebpackPlugin // copy文件目录
  • BannerPlugin // 给打包后的文件添加头注释
plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html',
            filename: 'home.html',
        }),
        new CleanWebpackPlugin('./dist'),   // 传入要删除的目录 也可传数组
        new CopyWebpackPlugin([{ from: './src/static', to: './dist' }]),   //须要拷贝的目录 必须是arr
        new webpack.BannerPlugin('make 2019 by beth.miao'),
    ],
复制代码

webpack跨域问题 配置代理 proxy

proxy: {
            '/api': {
                target: 'http://localhost:3001',
                pathRewrite: { '/api': '' }
            }
        }
复制代码

resolve 属性的配置

resolve: {  // 解析第三方包 common
        modules: [path.resolve('node_modules')],
        // mainFields: ['style', 'main'],
        // mainFiles: '',
        alias: {
            bootstrap: 'bootstrap/dist/css/bootstrap.css',
        },
        extensions: ['.js', '.css', '.json', 'vue'],    // 引入路径后缀名处理
    },
复制代码
相关文章
相关标签/搜索