Webpack 4 使用指南

最近想学一学Webpack,在网上看了不少相关文章,可是Webpack更新的太快了,不少文章都不适用weback新的版本,我从头开始研究了一番,在这里和你们分享交流一下,有错误的地方请指出.javascript

简介

  • 从头开始搭建一个Webpack项目
  • 遇到的各类警告
  • 打包js文件
  • 处理css文件
  • 插件使用
  • 提取公共js库
  • webpack-dev-server 等...

一 . 搭建一个webpack项目

首先你须要一个node.js (个人版本 node v8.9.4, npm v5.6.0 )
建立一个文件夹 mkdir webpack-my 进入文件夹 cd webpack-my
建立项目 npm init 一路回车
安装webpack webpack-cli(想要执行webpack的命令必须有这个包)
--save-dev 是只添加依赖到开发环境
npm install --save-dev webpack webpack-cli
window下执行应该有几条警告 警告虽然没多大关系但咱们仍是来看一下
WARN nomnom@1.8.1: Package no longer supported... nomnom包过期了不用管它
WARN babel-preset-es2015@6.24.1 babel推荐让使用 babel-preset-env 咱们下面再安装
WARN webpack-my@1.0.0 No repository field 没有仓库地址的警告能够在 npm init命令里设置或修改package.json:
css

"repository": {
    "type": "git",
    "url": "http://path.xxx"
}
复制代码

或者设置 "private": true 设置为私有
webpack-my@1.0.0 No description 没写描述,基本同上...
两个 WARN SKIPPING OPTIONAL DEPENDENCY: fsevents@1.1.3 fsevent是mac osx系统的,警告忽略之... (微强迫症,警告不看全不舒服...)html

二 . 处理js文件

1 . 安装babel

处理js文件咱们须要用到bable,先安装一下
npm install --save-dev babel-loader babel-core
java

2 . 安装 babel-preset-env

它用来转义es6等 babel-preset-env介绍
npm install --save-dev babel-preset-env
在根目录下建立 .babelrc 文件, 加入如下代码
node

{
    "presets": ["env"]
}
复制代码

3 . 解决浏览器兼容及性能问题

为防止浏览器不支持 Promise/Object.assign/Array.from等还有性能问题,咱们引入两个包:
webpack

npm install --save-dev babel-polyfill babel-plugin-transform-runtime
引入生产版本依赖 npm install --save babel-runtime 经过 .babelrc 添加配置git

{
    "presets": [
        "env"
    ],
    "plugins": [
       "transform-runtime"
    ]
}
复制代码

babel-polyfill 须要在 webpack中配置下面会说到es6

4 . 让咱们来配置一下webpack :

建立 src/bundle文件夹做为咱们存放/生成代码的地方
建立 webpack.config.js 文件做为webpack的配置文件
path为node.js内置的,用来处理路径的, __dirname是node.js的全局属性,表明当前路径。
将 babel-polyfill 加到你的 entry 数组中使用
配置js文件要通过babel转义github

const path = require('path');
module.exports = {
    //entry为入口,webpack从这里开始编译
    entry: [
        "babel-polyfill",
        path.join(__dirname, './src/index.js')
    ],
    //output为输出 path表明路径 filename表明文件名称
    output: {
        path: path.join(__dirname, './bundle'),
        filename: 'bundle.js'
    },
    //module是配置全部模块要通过什么处理
    //test:处理什么类型的文件,use:用什么,include:处理这里的,exclude:不处理这里的
    module: {
        rules: [
            {
                test: /\.js$/,
                use: ['babel-loader'],
                include: path.join(__dirname , 'src'),
                exclude: /node_modules/
            }
        ]
    },
};
复制代码

好了让咱们来试验一下,在src里建立 text-0.js text-1.js text-2.js index.js 内容分别为:web

export const Text0 = "小明";
复制代码
export const Text1 = "在公司";
复制代码
export const Text2 = "写代码";
复制代码
import {Text0} from './text-0.js';
import {Text1} from './text-1.js';
import {Text2} from './text-2.js';

const textFun = (...arg) => {
    let P = document.createElement("p");
    P.innerHTML = arg.join(" ");
    document.getElementById('root').appendChild(P);
}
textFun(Text0,Text1,Text2);
复制代码

5 . 使用webpack

控制台输入 npx webpack --config webpack.config.js npx是什么
根据webpack.config.js打包文件
等等出现了什么 WARNING in configuration The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment. You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/ 原来是让咱们设置开发或者生产模式
webpack.config.js 里设置

mode: 'development'
复制代码

为了方便使用咱们在 package.json 里加入webpack打包的命令方便咱们使用修改 script

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

这样再次运行咱们直接输入 npm run build
js文件打包好了,让咱们建立一个html页面看看效果吧,在bundle文件夹下建立 index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    </head>
    <body>
        <div id='root'></div>
        <script type="text/javascript" src="./bundle.js" charset="utf-8"></script>
    </body>
</html>
复制代码

注意在这里写了一个script标签引入 bundle.js
打开html文件看看效果吧


若是你想看看打包出来的js文件,你能够在 webpack.config.js 里添加 devtool 属性 属性配置
图简单的话直接配置 devtool: '' 就能够了.

三 . 处理less文件

1 . 安装处理 css 相关 loader

npm install --save-dev css-loader style-loader
css-loader让你能import css  , style-loader能将css以style的形式插入

2 . 安装 less 相关

npm install --save-dev less less-loader

3 . 安装 postcsspostcss-cssnext 添加浏览器前缀

npm install --save-dev postcss-loader postcss-cssnext
建立 postcss.config.js 加入如下代码

module.exports = {
    plugins: {
        'postcss-cssnext': {}
    }
}
复制代码

我在这里尝试 autoprefixer 插件可是好像无论用,可能还依赖别的包.

4 . 配置webpack

webpack.config.js -> module -> rules 里添加配置
处理顺序从右到左 less -> postcss -> css -> style

{
    test: /\.less$/,
    use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader']
}
复制代码

四 . 插件

1 . 生成HTML插件

安装插件
npm install --save-dev html-webpack-plugin 配置 webpack.config.js

const htmlWebpackPlugin = require('html-webpack-plugin');
...
plugins: [
    new htmlWebpackPlugin({
        filename: "index.html",  //打包后的文件名
        template: path.join(__dirname , "./src/index.html")  //要打包文件的路径
    })
],
复制代码

src 文件夹里建立一个 index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    </head>
    <body>
        <div id='root'></div>
    </body>
</html>
复制代码

html-webpack-plugin用法全解
删除 bundle 文件夹下全部文件
从新运行 npm run build 看看效果吧

2 . 生成CSS插件

安装插件(目前必须有@next)
npm install --save-dev extract-text-webpack-plugin@next
添加配置 webpack.config.js

const ExtractTextPlugin = require('extract-text-webpack-plugin');
...
module: {
    rules: [
        ...
        {
            test: /\.less$/,
            use: ExtractTextPlugin.extract({
                fallback: "style-loader",
                use: ['css-loader', 'postcss-loader', 'less-loader']
            })
        }
    ]
},
plugins: [
    ...
    new ExtractTextPlugin({
        filename: 'index.css'
    }),
],
复制代码

3 . 清理打包文件插件

上述代码所打出的包名称一直是同样的,很容易形成缓存问题
咱们在 webpack.config.js 中作一下修改
outoup 下的 filename: 'bundle.js'filename: 'bundle.[hash:8].js'
plugins -> ExtractTextPlugin 下的 filename: 'index.css'filename: 'index.[hash:8].css'
缓存的问题解决了,可是咱们每次生成的都是不一样名字的文件 bundle 文件夹里的东西愈来愈多,咱们须要一个插件来清理它.
安装插件 npm install --save-dev clean-webpack-plugin
修改 webpack.config.js

const CleanWebpackPlugin = require('clean-webpack-plugin');
...
plugins: [
    ...
    new CleanWebpackPlugin(['bundle'])
]
复制代码
====== 2018.09.26 update ======

4 . 代码压缩件插件

npm install uglifyjs-webpack-plugin -D 安装代码压缩插件
修改 webpack.config.js

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

五 . 提取公共js

webpack.config.js 里添加

output: {
    ...
    chunkFilename: '[name].[chunkhash:8].js'
},
...
optimization: {
    splitChunks: {
        cacheGroups: {
            vendor: {
                test: /[\\/]node_modules[\\/]/,
                name: 'common',
                chunks: 'all'
            }
        }
    }
},
复制代码

参考文章 webpack4 splitChunksPlugin && runtimeChunkPlugin 配置杂记

六 . webpack-dev-server配置

安装 webpack-dev-server
npm install --save-dev webpack-dev-server webpack.config.js 添加配置

...
devServer: {
    contentBase: path.join(__dirname, 'bundle'),  //启动路径
    host:'localhost',  //域名
    port: 8018,  //端口号
}
复制代码

执行命令 npx webpack-dev-server --config webpack.config.js
为了方便使用添加 package.json 中,加入 --color(颜色) --progress(进度) --hot(热加载)

"scripts": {
    "build": "npx webpack --config webpack.config.js",
    "start": "npx webpack-dev-server --config webpack.config.js --color --progress --hot"
 },
复制代码

七 . 编译图片

npm install --save-dev url-loader file-loader
webpack.config.js -> rules增长配置:

{
   test: /\.(png|jpg|gif)$/,
   use: [{
       loader: 'url-loader',
       options: {
           limit: 8192  //8k一下的转义为base64
       }
   }]
}
复制代码

总结

到这里一个拥有基础功能的webpack包就建好了,后续有什么想到的东西我会继续更新...
之后可能会加上React , 项目的代码放在个人github
第一次写文章,有什么问题请告诉我~

====== 2018.5.13 update ======

笔者回来慢慢填坑了

八 . CSS Modules 使用

使用 CSS Modules 来模块化咱们的CSS 修改咱们的 webpack.config.js -> module -> rules

{
    test: /\.less$/,
    use: ExtractTextPlugin.extract({
        fallback: "style-loader",
-       use: ['css-loader', 'postcss-loader', 'less-loader'],
+       use: ['css-loader?modules&localIdentName=[local]-[hash:base64:5]', 'postcss-loader', 'less-loader']
    })
}
复制代码

这样咱们全部通过 rulesless 名字都被加了hash了
在咱们的 index.less 中加入

.module-test{
    background-color: green;
    color: blue;
}
复制代码

对应咱们在 index.js 中加入

//替换以前的引入
import style from './index.less';

const textFun = (...arg) => {
    let P = document.createElement("p");
    P.innerHTML = arg.join(" ");
+   P.className = style["module-test"];
    document.getElementById('root').appendChild(P);
}
复制代码

运行 npm run build
好了咱们遇到一个问题,以前写的 #root 也被 CSS Modules 改变了 但是咱们的 #root 是写在 index.html 里的
咱们把 #root 改为这样 :global(#root) 这样就不会被改变了.

====== 2018.5.20 update ======

后续暂时没什么时间继续更新文章了(想开新坑...)。
我作了一些关于多页面打包、公共库提取、公共代码提取的配置
在个人 github
欢迎来访,同时求个star 求个Fork

====== 2018.07.15 update ======

热加载设置
webpack.config.js 中的 devServer 加入 hot: true
entry 入口添加 webpack/hot/only-dev-server 开启热加载
须要热加载的页面加入

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

开启热加载

注意这种配置在多页面状况下只有首页能够热模块加载 其余的页面不行

====== 2018.07.16 update ======

加上 source-map 能看清楚错误在哪一个文件
devtool: 'source-map'

参考文章

Webpack4 那点儿东西
从零搭建React全家桶框架教程
webpack中文网
babel中文网

相关文章
相关标签/搜索