这两天摆弄webpack,躺过很多坑,直到今天看了一位博主的文章才得以解决。他对配置中的各个部分做说明。
下面的配置99.9%抄自博主: https://www.cnblogs.com/nianyifenzhizuo/p/10271001.html
安装package.json中的node-sass可能因为网络原因不能成功安装
报错信息有一大串,其中提及python和gyp,其实不用去安装他们。只要执行下面的命令:
npm set sass_binary_site=https://npm.taobao.org/mirrors/node-sass/
npm i node-sass -D
以下为一个vue项目的基本配置:
项目根目录:
{ "name": "shop", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "clean": "rimraf dist", "build": "cross-env NODE_ENV=production webpack --config ./build/webpack.prod.conf.js", "dev": "cross-env NODE_ENV=development webpack-dev-server --config ./build/webpack.dev.conf.js", "start": "npm run clean && npm run build" }, "author": "asd", "license": "ISC", "devDependencies": { "@babel/core": "^7.2.2", "@babel/plugin-transform-runtime": "^7.2.0", "autoprefixer": "^9.4.6", "babel-loader": "^8.0.5", "babel-plugin-transform-remove-console": "^6.9.4", "clean-webpack-plugin": "^1.0.1", "cross-env": "^5.2.0", "css-loader": "^2.1.0", "file-loader": "^3.0.1", "html-webpack-plugin": "^3.2.0", "mini-css-extract-plugin": "^0.5.0", "node-sass": "^4.11.0", "optimize-css-assets-webpack-plugin": "^5.0.1", "postcss-loader": "^3.0.0", "purify-css": "^1.2.5", "purifycss-webpack": "^0.7.0", "rimraf": "^2.6.3", "sass-loader": "^7.1.0", "style-loader": "^0.23.1", "uglifyjs-webpack-plugin": "^2.1.1", "url-loader": "^1.1.2", "vue-loader": "^15.6.2", "vue-style-loader": "^4.1.2", "vue-template-compiler": "^2.5.22", "webpack": "^4.29.0", "webpack-cli": "^3.2.1", "webpack-dev-server": "^3.1.14", "webpack-merge": "^4.2.1" }, "dependencies": { "@babel/preset-env": "^7.3.1", "@babel/runtime": "^7.3.1", "axios": "^0.18.0", "body-parser": "^1.18.3", "cookie-parser": "^1.4.4", "express": "^4.16.4", "glob-all": "^3.1.0", "mongoose": "^5.4.11", "vue": "^2.5.22", "vue-lazyload": "^1.2.6", "vue-router": "^3.0.2" } }
module.exports = { loader: 'postcss-loader', plugins: [ require('autoprefixer') ] }
{ "presets": [ [ "@babel/preset-env", { "modules": false } ] ], "plugins": [ "@babel/plugin-transform-runtime", [ "transform-remove-console", { "include": ["error", "warn"] } ] ] }
项目根目录=>build文件夹
const webpack = require('webpack')
const { resolve }= require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const isDev = process.env.NODE_ENV === 'production'
let pluginsConfig = [
new VueLoaderPlugin(),
new HtmlWebpackPlugin({
title: 'my App',
template: resolve(__dirname, '../src/index.html')
}),
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify(process.env.NODE_ENV)
}
})
]
if (!isDev) {
pluginsConfig = pluginsConfig.concat(new MiniCssExtractPlugin({
filename: "css/[name]_[contenthash].css"
}))
}
module.exports = {
mode: process.env.NODE_ENV || 'production',
entry: resolve(__dirname, '../src/index.js'),
output: {
filename: 'bundle.js',
path: resolve(__dirname, '../dist')
},
resolve: {
//引入时可以省略后缀
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
//@就了代表了src文件夹所在路径
'@': resolve('src'),
}
},
module: {
rules: [{
test: /.vue$/,
loader: 'vue-loader'
},
{
test: /.scss$/,
use: [
isDev ? 'vue-style-loader' : MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[local]_[hash:base64:8]'
}
},
'sass-loader'
]
},
{
test: /.(png|jpg|gif)$/,
loader: 'url-loader?name=images/[name]-[contenthash:5].[ext]&limit=2000'
},
{
test: /.js$/,
loader: 'babel-loader?cacheDirectory',
exclude: '/node_modules/',
include: resolve(__dirname, '../src')
}
]
},
plugins: pluginsConfig,
}
const webpack = require('webpack')
const path = require('path')
const WebPackBaseConfig = require('./webpack.base.conf.js')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const WebPackMerge = require('webpack-merge')
module.exports = WebPackMerge(WebPackBaseConfig, {
devtool: 'inline-source-map',
devServer: {
contentBase: path.join(__dirname, 'dist'), //告诉服务器从哪个目录中提供内容
compress: true, //启用 gzip 压缩
port: 9000, //端口号
host: '0.0.0.0', //默认是 localhost。如果希望服务器外部可访问,则设置为0.0.0.0
hot: true //启用热替换模块 必须配置 webpack.HotModuleReplacementPlugin
},
plugins: [
new CleanWebpackPlugin(['dist']), //清理文件夹
new webpack.HotModuleReplacementPlugin(), //启用热替换模块
new webpack.NamedModulesPlugin() //启用HMR时,插件将显示模块的相对路径
]
})
const webpack = require('webpack')
const path = require('path')
const WebPackMerge = require('webpack-merge')
const WebPackBaseConfig = require('./webpack.base.conf.js')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const glob = require('glob-all')
const PurifyCSSPlugin = require('purifycss-webpack')
module.exports = WebPackMerge(WebPackBaseConfig, {
output: {
filename: '[name].js',
chunkFilename: '[name].[chunkhash:5].js',
path: path.resolve(__dirname, 'dist')
},
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\/]node_modules[\/]/,
name: 'vendors',
chunks: 'all'
}
}
},
runtimeChunk: true,
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true
}),
new OptimizeCSSAssetsPlugin()
]
},
plugins: [
new PurifyCSSPlugin({
paths: glob.sync([
path.join(__dirname, '../src/')
]),
purifyOptions: {
whitelist: ['*purify*']
}
}),
]
})
项目根目录=>src文件夹
import Vue from 'vue' import router from './router/index.js' new Vue({ el: '#app', router })
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset='utf-8'>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="renderer" content="webkit|ie-comp|ie-stand">
<title></title>
</head>
<body>
<div id="app" v-cloak>
<router-view></router-view>
</div>
</body>
</html>
<template>
<div id="app">
<img src="./assets/logo.png">
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
项目根目录=>src文件夹=>router文件夹
import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'HelloWorld', component: HelloWorld } ] })
项目根目录=>src文件夹=>components文件夹
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<h2>Essential Links</h2>
<ul>
<li>
<a
href="https://vuejs.org"
target="_blank"
>
Core Docs
</a>
</li>
<li>
<a
href="https://forum.vuejs.org"
target="_blank"
>
Forum
</a>
</li>
<li>
<a
href="https://chat.vuejs.org"
target="_blank"
>
Community Chat
</a>
</li>
<li>
<a
href="https://twitter.com/vuejs"
target="_blank"
>
Twitter
</a>
</li>
<br>
<li>
<a
href="http://vuejs-templates.github.io/webpack/"
target="_blank"
>
Docs for This Template
</a>
</li>
</ul>
<h2>Ecosystem</h2>
<ul>
<li>
<a
href="http://router.vuejs.org/"
target="_blank"
>
vue-router
</a>
</li>
<li>
<a
href="http://vuex.vuejs.org/"
target="_blank"
>
vuex
</a>
</li>
<li>
<a
href="http://vue-loader.vuejs.org/"
target="_blank"
>
vue-loader
</a>
</li>
<li>
<a
href="https://github.com/vuejs/awesome-vue"
target="_blank"
>
awesome-vue
</a>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped, lang="sass" src='@/assets/css/admin.scss'></style>
项目根目录=>src文件夹=>assets文件夹=>css
h1, h2 { font-weight: normal; } ul { list-style-type: none; padding: 0; } li { display: inline-block; margin: 0 10px; } $link-color: #ff6000; a { color: $link_color; }