本文共 7885 字,大约阅读时间需要 26 分钟。
最近搞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, 内容如下
目录结构如下 包括打包<%= htmlWebpackPlugin.options.title %> <% for (var i = 0, item; item = htmlWebpackPlugin.options.js[i++];) { %> <% } %>
运行一下 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" }}
以上可能有不准确的或者冗余地方 请酌情参考
有需要的交流的可以加个好友