最近搞vue,用的vue-cli,快速構建開發環境,當然核心還是集成的webpack。之前自己做react的webpack環境配置總覺得差強人意,於是就把vue-cli的遷移過來,感覺還是不錯的。對應一般開發需要,下面需要修改的就在build和config目錄下的幾個文件中
從webpack.base.conf.js 文件開始,無論生產環境還是開發環境都以這個爲基礎的,
module.exports = {
entry: {
app: ['./src/js/index.js'], //入口文件
babel: ['babel-polyfill'] //babel-polyfill 和redux 單獨打包減小app.js 的打包體積 用於配合externals
redux: ['redux', 'react-redux'],
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath,
libraryTarget: 'umd' //用於外部引入的 react.js 等
},
resolve: {
extensions: ['.js', '.json'],
symlinks: false
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test')],
exclude:[resolve('node_modules')], //在node_modules的文件不被babel理會
query: {
presets: ['react', 'stage-2']
}
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]'),
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
},
// {
// test: /\.less$/,
// use: ExtractTextPlugin.extract({ use: extractCssLoaders, fallback: 'style-loader' }),
// }
]
},
// 配置全局使用
plugins: [
new webpack.ProvidePlugin({
"React": "react",
"ReactDOM": "react-dom",
"_": "lodash",
"classnames":"classnames"
}),
//extract css into its own file
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css')
}),
],
// 單獨提取出 react 減小打包文件大小
externals: {
'react-router': {
amd: 'react-router',
root: 'ReactRouter',
commonjs: 'react-router',
commonjs2: 'react-router'
},
react: {
amd: 'react',
root: 'React',
commonjs: 'react',
commonjs2: 'react'
},
'react-dom': {
amd: 'react-dom',
root: 'ReactDOM',
commonjs: 'react-dom',
commonjs2: 'react-dom'
}
}
}
然後再 util.js 文件裏,主要就在cssLoaders
exports.cssLoaders = function (options) {
options = options || {}
var cssLoader = {
loader: 'css-loader',
options: {
minimize: process.env.NODE_ENV === 'production',
sourceMap: options.sourceMap,
modules: true,
localIdentName: '[local]--[hash:base64:6]', //class 名字 代替
}
}
// generate loader string to be used with extract text plugin
function generateLoaders(loader, loaderOptions) {
var loaders = [cssLoader];
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
// Extract CSS when that option is specified
//(which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
publicPath: '../../', //解決 build css bg img 加載路徑不對問題
fallback: 'react-style-loader' // 修改vue-style-loader
})
} else {
return ['react-style-loader'].concat(loaders)
}
}
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less'),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass'),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}
webpack.prod.conf 生產環境的修改,打包時,redux,和babel-polyfill 分離打包配置 配合webpack.base.conf.js中entry修改
new webpack.optimize.CommonsChunkPlugin({
name: ['app', 'redux', 'babel'], //單獨提取打包
filename: './static/js/[name].js',
minChunks: ({resource}) => {
resource &&
/\.js$/.test(resource) &&
resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
chunks: ['app', 'redux', 'babel']
}),
webpack.dev.conf.js和webpack.prod.conf.js 有同一個地方修要, 用於在inde.html上寫入外部js
new HtmlWebpackPlugin({
title: config.title,
filename: 'index.html',
template: 'index.ejs', //修改模板類型 爲ejs
inject: true,
js: config.externalsJs_dev // 開發環境是config.externalsJs_prod
}),
當然config.externalsJs_dev 配置到了 config/index.js 中
// 提取出的文件鏈接
externalsJs_dev:[
'https://cdn.bootcss.com/react/16.0.0/umd/react.development.js',
'https://cdn.bootcss.com/react-dom/16.0.0/umd/react-dom.development.js',
'https://cdn.bootcss.com/react-router/4.2.0/react-router.js'
],
externalsJs_prod: [
'https://cdn.bootcss.com/react/16.0.0/umd/react.production.min.js',
'https://cdn.bootcss.com/react-dom/16.0.0/umd/react-dom.production.min.js',
'https://cdn.bootcss.com/react-router/4.2.0/react-router.min.js'
],
title: 'react-redux-demo' //模板標題
刪除項目 根目錄下的index.html 改爲index.ejs, 內容如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<div id="root"></div>
<% for (var i = 0, item; item = htmlWebpackPlugin.options.js[i++];) { %>
<script type="text/javascript" src="<%= item %>"></script>
<% } %>
</body>
</html>
目錄結構如下 包括打包運行一下 npm run build --report=true 看看打包分析, 暫時未集成babel-runtime
是否要集成babel-runtime 需要修改 .babelrc 文件中
"plugins": ["transform-runtime"],
取消此行的註釋, 打包分析如下
package.json 內容 整個修改後的依賴
{
"name": "wz",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "node build/dev-server.js",
"start": "node build/dev-server.js",
"build": "node build/build.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"cross-env": "^5.0.5",
"expect": "^1.20.1",
"node-libs-browser": "^2.0.0",
"node-sass": "^4.5.3",
"npm": "^5.3.0",
"react": "^15.6.1",
"react-addons-test-utils": "^15.1.0",
"react-dom": "^15.6.1",
"react-redux": "^5.0.4",
"redux": "^3.5.2",
"redux-logger": "^3.0.1",
"redux-promise": "^0.5.3",
"redux-thunk": "^2.1.0",
"shelljs": "^0.7.8",
"style-loader": "^0.18.2"
},
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-core": "^6.10.4",
"babel-loader": "^7.1.2",
"babel-plugin-react-transform": "^2.0.2",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-polyfill": "^6.9.1",
"babel-preset-env": "^1.3.2",
"babel-preset-react": "^6.11.1",
"babel-preset-stage-0": "^6.5.0",
"babel-preset-stage-2": "^6.22.0",
"babel-register": "^6.9.0",
"bower-webpack-plugin": "^0.1.9",
"chalk": "^2.0.1",
"chromedriver": "^2.27.2",
"compression-webpack-plugin": "^1.0.0",
"connect-history-api-fallback": "^1.3.0",
"copy-webpack-plugin": "^4.1.1",
"core-js": "^2.0.0",
"cross-spawn": "^5.0.1",
"css-loader": "^0.28.5",
"cssnano": "^3.10.0",
"eventsource-polyfill": "^0.9.6",
"express": "^4.14.1",
"extract-text-webpack-plugin": "^3.0.1",
"file-loader": "^1.1.5",
"friendly-errors-webpack-plugin": "^1.6.1",
"html-webpack-plugin": "^2.29.0",
"http-proxy-middleware": "^0.17.3",
"less": "^2.7.2",
"less-loader": "^4.0.3",
"minimist": "^1.2.0",
"open": "0.0.5",
"opn": "^5.1.0",
"optimize-css-assets-webpack-plugin": "^3.0.0",
"ora": "^1.3.0",
"postcss-import": "^10.0.0",
"postcss-loader": "^2.0.6",
"precss": "^2.0.0",
"react-style-loader": "^1.0.1",
"react-transform-hmr": "^1.0.4",
"rimraf": "^2.6.0",
"url-loader": "^0.6.2",
"webpack": "^3.5.5",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-dev-middleware": "^1.6.1",
"webpack-dev-server": "^2.4.4",
"webpack-hot-middleware": "^2.11.0",
"webpack-merge": "^4.1.0"
},
"engines": {
"node": ">= 4.0.0",
"npm": ">= 3.0.0"
}
}
以上可能有不準確的或者冗餘地方 請酌情參考
有需要的交流的可以加個好友