有输入必须有输出,今天就来输出一下学习webpack的过程。
不得不先吐槽一下,比起可爱的grunt和好用的gulp,对webpack真心爱不起来!
还有一个血的教训:千万不要偷懒,有问题直接去官网。。。
本文旨在记录学习webpack的过车和遇到的问题,适合对node和webpack基础知识有些了解的开发人员,不会详细到记录操作命令;还有些问题无解,还请高手指教。
首先贴上搭建时候各种包的版本,毕竟webpack每次升级兼容性都不太好
操作系统:windows 10;node:v8.9.4
搭建步骤
1、安装webpack,webpack-cli,webpack-dev-server html-webpack-server (webpack-cli在4.x的版本中已经被抽离,这里需要再安装一下);
对应配置:
a、在package.json的scripts中配置启动server的命令。
b、在webpack.config.js中配置入口,出口,以及server;
有关server的更多配置参数请参考 https://webpack.js.org/configuration/dev-server/#src/components/Sidebar/Sidebar.jsx
c、配置html-webpack-plugin,在编译后的文件夹自动生成一个html,并且已经添加了编译后的入口js;
配置后webpack.config.js:(这时候我们就可以直接用 npm run dev 来启动服务了。)
const webpack = require(‘webpack‘);const path = require(‘path‘);const HtmlWebpackPlugin = require(‘html-webpack-plugin‘);module.exports = { ???entry:{//入口文件,这里可以配置多个入口 ???????main: path.resolve(__dirname,‘src/module/index/main.js‘), ???????//plugin: path.resolve(__dirname,‘src/plugin/plugin.js‘) ???}, ???output: {//打包后文件位置以及文件名 ???????path: path.resolve(__dirname,‘dist‘), ???????filename: ‘[name].js‘ ????}, ???devServer: {//server配置 ???????contentBase: path.join(__dirname,"dist"), //服务指向的文件夹 ???????port: 9000,//端口号 ???????inline: true,//自动刷新模式配置为inline ???????open: true, //是否自动打开页面 ???????proxy: { //代理配置 ???????????"/dist": { ???????????????target: "http://localhost:3000", ???????????????pathRewrite: { ???????????????????"^/api": "" ???????????????}, ???????????????bypass: function(req, res, proxyOptions){ ???????????????????//代理过滤函数 ???????????????????return "" ???????????????} ???????????} ???????} ???}, ???plugins: [ ???????new HtmlWebpackPlugin({ ???????????//配置生成新html的源html ???????????template: path.resolve(__dirname,‘src/index.html‘) ???????}) ????]}
2、配置loader
a、安装js处理包:babel-loader babel-ccore babel-preset-env并配置
babel-preset-env 可以根据配置的env只编译那些还不支持的特性,详情请参考https://github.com/babel/babel-preset-env
{ ???test: /\.js$/, ???use: { ???????loader: ‘babel-loader‘, ???????options: { ???????????presets: [‘env‘], ???????????cacheDirectory: true //配置允许缓存,加快编译速度 ???????} ???}}
b、安装css处理包 node-sass sass-loader(代码中使用sass,less的配置跟sass一样,只要安装less对应的处理插件即可)
安装css分离处理插件 extract-webpack-text-plugin,把css样式从html页面摘出来放到单独的文件中
sass-loader 依赖于 node-sass,所以这里不要忘记安装 node-sass;
首先引入extract-webpack-text-plugin,并new出两个对象来,分别处理css和less,传参为处理后样式的保存路径:
const ExtractTextPlugin = require("extract-text-webpack-plugin");const extractCss = new ExtractTextPlugin(‘css/[name].css‘);const extractLess = new ExtractTextPlugin(‘css/[name].css‘);
module中配置loader的rules:
{ ???test: /\.scss$/, ???use: extractLess.extract(["css-loader","sass-loader"])},{ ???test: /\.css$/, ???use: extractCss.extract({ ????????fallback: "style-loader", ?????????use: "css-loader" ???})},
plugins里添加extractCss和extractLess插件:
plugins: [ ???new HtmlWebpackPlugin({ ???????template: path.resolve(__dirname,‘src/index.html‘) ???}), ???extractCss, ???extractLess]
c、img,字体等文件loader安装配置 url-loader file-loader
注意:文档里介绍url-loader是基于file-loader封装的支持更多配置的loader,但是经测试发现,url-loader并不能单独使用,需要同时安装file-loader才可
哪位同学如果知道原因还请留言,先感谢!
{//加载图片loader配置 ???test: /\.(png|jpg|gif)$/, ???????use: [ ???????{ ???????????loader: ‘url-loader‘, ???????????options: { ?????????????limit: 8192 //大小限制 ???????????} ???????} ???]},{//加载字体等loader配置 ???test: /\.(eot|svg|ttf|woff|woff2)(\?\S*)?$/, ???use:{ ???????loader: ‘file-loader‘ ???}}
3、其他插件配置
uglifyJsPlugin,这个插件在4.x的版本中,也已经被独立出来,需要单独安装才能使用。
关于模块热加载的开启,官方文档中给出多种实现,这里给出使用devServer实现方式的测试:
其他实现方式详情参考 https://doc.webpack-china.org/guides/hot-module-replacement
在devServer 中设置 hot: true,在plugins中添加webpack.HotModuleReplacementPlugin();
测试结果:
修改html文件:浏览器打出HMR字样的提示,但是页面并没有变化:
修改js文件:编译后页面完全刷新;
当我打算继续配置多入口多页面时,竟然发现我只能循环调用 html-webpack-plugin来生成html;
到目前位置,webpack给我的感觉就是编译速度慢,文档介绍不清晰以至于奇奇怪怪的bug一个又一个,这些感受大概是因为学习不够深入,不够细致。
最后,贴出package.json和webpack.config.js
{ ?"name": "webpackOnly", ?"version": "1.0.0", ?"description": "", ?"main": "index.js", ?"scripts": { ???"test": "echo \"Error: no test specified\" && exit 1", ???"dev": "webpack-dev-server" ?}, ?"keywords": [], ?"author": "", ?"license": "ISC", ?"devDependencies": { ???"babel-core": "^6.26.0", ???"babel-loader": "^7.1.4", ???"babel-preset-env": "^1.6.1", ???"css-loader": "^0.28.11", ???"extract-text-webpack-plugin": "^4.0.0-beta.0", ???"file-loader": "^1.1.11", ???"html-webpack-plugin": "^3.2.0", ???"node-sass": "^4.8.3", ???"sass-loader": "^7.0.1", ???"style-loader": "^0.21.0", ???"uglifyjs-webpack-plugin": "^1.2.5", ???"url-loader": "^1.0.1", ???"webpack": "^4.6.0", ???"webpack-cli": "^2.0.15", ???"webpack-dev-server": "^3.1.3" ?}, ?"dependencies": { ???"element-ui": "^2.3.6" ?}}
const webpack = require(‘webpack‘);const path = require(‘path‘);const HtmlWebpackPlugin = require(‘html-webpack-plugin‘);const UglifyJsPlugin = require(‘uglifyjs-webpack-plugin‘);const ExtractTextPlugin = require("extract-text-webpack-plugin");const extractCss = new ExtractTextPlugin(‘css/[name].css‘);const extractLess = new ExtractTextPlugin(‘css/[name].css‘);module.exports = { ???entry:{//入口文件,这里可以配置多个入口 ???????main: path.resolve(__dirname,‘src/module/index/main.js‘), ???????plugin: path.resolve(__dirname,‘src/plugin/plugin.js‘) ???}, ???output: {//打包后文件位置以及文件名 ???????path: path.resolve(__dirname,‘dist‘), ???????filename: ‘[name].js‘ ????}, ???devServer: {//server配置 ???????contentBase: path.join(__dirname,"dist"), //服务指向的文件夹 ???????port: 9000,//端口号 ???????inline: true,//自动刷新模式配置为inline ???????open: true, //是否自动打开页面 ???????hot: true, ???????proxy: { //代理配置 ???????????"/dist": { ???????????????target: "http://localhost:3000", ???????????????pathRewrite: { ???????????????????"^/api": "" ???????????????}, ???????????????bypass: function(req, res, proxyOptions){ ???????????????????//代理过滤函数 ???????????????????return "" ???????????????} ???????????} ???????} ???}, ???plugins: [ ???????new HtmlWebpackPlugin({ ???????????template: path.resolve(__dirname,‘src/index.html‘) ???????}), ???????new UglifyJsPlugin({ ???????????uglifyOptions: { ???????????????compress: false ???????????} ???????}), ???????new webpack.HotModuleReplacementPlugin(),//热加载插件 ???????extractCss, ???????extractLess ???], ???module: { ???????rules: [ ???????????{ ???????????????test: /\.js$/, ???????????????use: { ???????????????????loader: ‘babel-loader‘, ???????????????????options: { ???????????????????????presets: [‘env‘], ???????????????????????cacheDirectory: true //配置允许缓存,加快编译速度 ???????????????????} ???????????????} ???????????}, ???????????{ ???????????????test: /\.scss$/, ???????????????use: extractLess.extract(["css-loader","sass-loader"]) ???????????????/*use: [{ //不使用css抽离的配置方式 ???????????????????loader: ‘style-loader‘ ???????????????},{ ???????????????????loader: ‘css-loader‘ ???????????????},{ ???????????????????loader: ‘sass-loader‘, ???????????????????options: { ???????????????????????includePaths: ["src"] ???????????????????} ???????????????}]*/ ???????????}, ???????????{ ???????????????test: /\.css$/, ???????????????use: extractCss.extract({ ????????????????????fallback: "style-loader", ?????????????????????use: "css-loader" ???????????????}) ???????????}, ???????????{ ???????????????test: /\.(png|jpg|gif)$/, ???????????????use: [ ???????????????????{ ???????????????????????loader: ‘url-loader‘, ???????????????????????options: { ?????????????????????????limit: 8192 ???????????????????????} ???????????????????} ???????????????] ???????????}, ???????????{ ???????????????test: /\.(eot|svg|ttf|woff|woff2)(\?\S*)?$/, ???????????????use:{ ???????????????????loader: ‘file-loader‘ ???????????????} ???????????} ???????] ???}}
webpack4.x学习笔记
原文地址:https://www.cnblogs.com/solaZhan/p/8945236.html