开发控制台中的Webpack2路径显示实际文件名

时间:2017-06-15 18:43:30

标签: javascript webpack sass

我们刚刚从webpack1迁移到webpack2,升级后有些样式无法正确呈现。

当我查看开发控制台中当前已损坏的DOM元素时,我看到现在控制台正在显示实际文件的路径,而在旧版本中它只是显示文件名。此外,当悬停在文件名上时,它将显示相对路径,但以' webpack:///.src/..'

开头

以下是devconsole的两个独立屏幕截图,以显示我的意思:

enter image description here

以下是两个webpack配置文件:

版本2(提供文件路径)

import webpack from 'webpack';
import autoprefixer from 'autoprefixer';
import cssnano from 'cssnano';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import config from '../config';
import _debug from 'debug';
const debug = _debug('app:webpack:config');
const paths = config.utils_paths;
const {__DEV__, __PROD__, __TEST__} = config.globals;

debug('Create configuration.');
const webpackConfig = {
  name: 'client',
  target: 'web',
  devtool: 'source-map',
  resolve: {
    modules: [
      paths.base(config.dir_client),
      'node_modules'
    ],
    extensions: ['.js', '.jsx']
  },
  module: {}
};
// ------------------------------------
// Entry Points
// ------------------------------------
const APP_ENTRY_PATH = paths.base(config.dir_client) + '/main.js';

webpackConfig.entry = {
  app: __DEV__
    ? [APP_ENTRY_PATH, `webpack-hot-middleware/client?path=${config.compiler_public_path}__webpack_hmr`]
    : [APP_ENTRY_PATH],
  bootstrap: 'bootstrap-loader',
  vendor: config.compiler_vendor
};

// ------------------------------------
// Bundle Output
// ------------------------------------
webpackConfig.output = {
  filename: `[name].[${config.compiler_hash_type}].js`,
  path: paths.base(config.dir_dist),
  publicPath: config.compiler_public_path
};

// ------------------------------------
// Plugins
// ------------------------------------
webpackConfig.plugins = [
  new webpack.DefinePlugin(config.globals),
  new webpack.ProvidePlugin({
    'jQuery': 'jquery',
    '$': 'jquery'
  }),
  new HtmlWebpackPlugin({
    template: paths.client('index.html'),
    hash: false,
    favicon: paths.client('static/favicon.ico'),
    filename: 'index.html',
    inject: 'body',
    minify: {
      collapseWhitespace: true
    }
  })
];

if (__DEV__) {
  debug('Enable plugins for live development (HMR, NoErrors).');
  webpackConfig.plugins.push(
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoEmitOnErrorsPlugin()
  );
} else if (__PROD__) {
  debug('Enable plugins for production (UglifyJS).');
  webpackConfig.plugins.push(
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        unused: true,
        dead_code: true,
        warnings: false
      }
    })
  );
}

// Don't split bundles during testing, since we only want import one bundle
if (!__TEST__) {
  webpackConfig.plugins.push(
    new webpack.optimize.CommonsChunkPlugin({
      names: ['vendor']
    })
  );
}

// ------------------------------------
// This used to be called 'Pre-Loaders'. Now 'Rules' enforcing 'pre'
// ------------------------------------
webpackConfig.module.rules = [
  {
    test: /\.(js|jsx)$/,
    enforce: 'pre',
    loader: 'eslint-loader',
    include: /src/,
    options: {
      configFile: paths.base('.eslintrc'),
      emitWarning: __DEV__
    }
  }
];

// ------------------------------------
// Used to be called 'Loaders'.  Now 'Rules'
// ------------------------------------
// JavaScript / JSON
webpackConfig.module.rules.push({
  test: /\.(js|jsx)$/,
  exclude: /node_modules/,
  use: [
    { loader: 'babel-loader',
      options: {
        cacheDirectory: true,
        plugins: ['transform-runtime'],
        presets: __DEV__
          ? ['es2015', 'react', 'stage-0', 'react-hmre']
          : ['es2015', 'react', 'stage-0']
      }
    }
  ]
});

// Styles
const cssLoader = !config.compiler_css_modules
  ? {loader: 'css-loader', options: {sourceMap: true}}
  : {loader: 'css-loader',
    options: {
      modules: true,
      sourceMap: true,
      importLoaders: 1,
      localIdentName: '[name]__[local]___[hash:base64:5]'
    }};

const postCssLoader = {
  loader: 'postcss-loader',
  options: {
    plugins: () => [
      autoprefixer({
        add: true,
        remove: true,
        browsers: ['last 2 versions']
      }),
      cssnano(
        {preset:
        ['default',
          {
            discardComments: {
              removeAll: true
            }
          }
        ]
        })],
    safe: true,
    sourceMap: true
  }
};

webpackConfig.module.rules.push({
  test: /\.scss$/,
  include: /src/,
  use: [
    'style-loader',
    cssLoader,
    postCssLoader,
    {loader: 'sass-loader', options: {sourceMap: true, includePaths: [paths.client('styles')]}}
  ]
});

webpackConfig.module.rules.push({
  test: /\.css$/,
  include: /src/,
  use: [
    'style-loader',
    cssLoader,
    postCssLoader
  ]
});

// Don't treat global SCSS as modules
webpackConfig.module.rules.push({
  test: /\.scss$/,
  exclude: /src/,
  use: [
    'style-loader',
    'css-loader?sourceMap',
    postCssLoader,
    {loader: 'sass-loader', options: {sourceMap: true, includePaths: [paths.client('styles')]}}
  ]
});

// Don't treat global, third-party CSS as modules
webpackConfig.module.rules.push({
  test: /\.css$/,
  exclude: /src/,
  use: [
    'style-loader',
    'css-loader?sourceMap',
    postCssLoader
  ]
});

// File loaders
/* eslint-disable */
webpackConfig.module.rules.push(
  { test: /\.woff(\?.*)?$/,  loader: 'url-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=application/font-woff' },
  { test: /\.woff2(\?.*)?$/, loader: 'url-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=application/font-woff2' },
  { test: /\.otf(\?.*)?$/,   loader: 'file-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=font/opentype' },
  { test: /\.ttf(\?.*)?$/,   loader: 'url-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=application/octet-stream' },
  { test: /\.eot(\?.*)?$/,   loader: 'file-loader?prefix=fonts/&name=[path][name].[ext]' },
  { test: /\.svg(\?.*)?$/,   loader: 'url-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=image/svg+xml' },
  { test: /\.(png|jpg)$/,    loader: 'url-loader?limit=8192' }
)
/* eslint-enable */

export default webpackConfig;

版本1(似乎正确)

import webpack from 'webpack';
import cssnano from 'cssnano';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import config from '../config';
import _debug from 'debug';

const debug = _debug('app:webpack:config');
const paths = config.utils_paths;
const {__DEV__, __PROD__, __TEST__} = config.globals;

debug('Create configuration.');
const webpackConfig = {
  name: 'client',
  target: 'web',
  devtool: 'source-map',
  resolve: {
    root: paths.base(config.dir_client),
    extensions: ['', '.js', '.jsx']
  },
  module: {}
};
// ------------------------------------
// Entry Points
// ------------------------------------
const APP_ENTRY_PATH = paths.base(config.dir_client) + '/main.js';

webpackConfig.entry = {
  app: __DEV__
    ? [APP_ENTRY_PATH, `webpack-hot-middleware/client?path=${config.compiler_public_path}__webpack_hmr`]
    : [APP_ENTRY_PATH],
  bootstrap: 'bootstrap-loader',
  vendor: config.compiler_vendor
};

// ------------------------------------
// Bundle Output
// ------------------------------------
webpackConfig.output = {
  filename: `[name].[${config.compiler_hash_type}].js`,
  path: paths.base(config.dir_dist),
  publicPath: config.compiler_public_path
};

// ------------------------------------
// Plugins
// ------------------------------------
webpackConfig.plugins = [
  new webpack.DefinePlugin(config.globals),
  new webpack.ProvidePlugin({
      'jQuery': 'jquery',
      '$': 'jquery',
  }),
  new HtmlWebpackPlugin({
    template: paths.client('index.html'),
    hash: false,
    favicon: paths.client('static/favicon.ico'),
    filename: 'index.html',
    inject: 'body',
    minify: {
      collapseWhitespace: true
    }
  })
];

if (__DEV__) {
  debug('Enable plugins for live development (HMR, NoErrors).');
  webpackConfig.plugins.push(
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin()
  );
} else if (__PROD__) {
  debug('Enable plugins for production (OccurenceOrder, Dedupe & UglifyJS).');
  webpackConfig.plugins.push(
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.optimize.DedupePlugin(),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        unused: true,
        dead_code: true,
        warnings: false
      }
    })
  );
}

// Don't split bundles during testing, since we only want import one bundle
if (!__TEST__) {
  webpackConfig.plugins.push(
    new webpack.optimize.CommonsChunkPlugin({
      names : ['vendor']
    })
  )
}

// ------------------------------------
// Pre-Loaders
// ------------------------------------
webpackConfig.module.preLoaders = [{
  test: /\.(js|jsx)$/,
  loader: 'eslint',
  exclude: /node_modules/
}];

webpackConfig.eslint = {
  configFile: paths.base('.eslintrc'),
  emitWarning: __DEV__
};

// ------------------------------------
// Loaders
// ------------------------------------
// JavaScript / JSON
webpackConfig.module.loaders = [{
  test: /\.(js|jsx)$/,
  exclude: /node_modules/,
  loader: 'babel',
  query: {
    cacheDirectory: true,
    plugins: ['transform-runtime'],
    presets: __DEV__
      ? ['es2015', 'react', 'stage-0', 'react-hmre']
      : ['es2015', 'react', 'stage-0']
  }
},
{
  test: /\.json$/,
  loader: 'json'
}
];


// Styles
const cssLoader = !config.compiler_css_modules
  ? 'css?sourceMap'
  : [
    'css?modules',
    'sourceMap',
    'importLoaders=1',
    'localIdentName=[name]__[local]___[hash:base64:5]'
  ].join('&');

webpackConfig.module.loaders.push({
  test: /\.scss$/,
  include: /src/,
  loaders: [
    'style',
    cssLoader,
    'postcss',
    'sass?sourceMap'
  ]
});

webpackConfig.module.loaders.push({
  test: /\.css$/,
  include: /src/,
  loaders: [
    'style',
    cssLoader,
    'postcss'
  ]
});

// Don't treat global SCSS as modules
webpackConfig.module.loaders.push({
  test: /\.scss$/,
  exclude: /src/,
  loaders: [
    'style',
    'css?sourceMap',
    'postcss',
    'sass?sourceMap'
  ]
});

// Don't treat global, third-party CSS as modules
webpackConfig.module.loaders.push({
  test: /\.css$/,
  exclude: /src/,
  loaders: [
    'style',
    'css?sourceMap',
    'postcss'
  ]
});

webpackConfig.sassLoader = {
  includePaths: paths.client('styles')
};

webpackConfig.postcss = [
  cssnano({
    autoprefixer: {
      add: true,
      remove: true,
      browsers: ['last 2 versions']
    },
    discardComments: {
      removeAll: true
    },
    safe: true,
    sourcemap: true
  })
];

// File loaders
/* eslint-disable */
webpackConfig.module.loaders.push(
  { test: /\.woff(\?.*)?$/,  loader: 'url?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=application/font-woff' },
  { test: /\.woff2(\?.*)?$/, loader: 'url?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=application/font-woff2' },
  { test: /\.otf(\?.*)?$/,   loader: 'file?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=font/opentype' },
  { test: /\.ttf(\?.*)?$/,   loader: 'url?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=application/octet-stream' },
  { test: /\.eot(\?.*)?$/,   loader: 'file?prefix=fonts/&name=[path][name].[ext]' },
  { test: /\.svg(\?.*)?$/,   loader: 'url?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=image/svg+xml' },
  { test: /\.(png|jpg)$/,    loader: 'url?limit=8192' }
)
/* eslint-enable */

export default webpackConfig;

config文件未更改。我查看了webpack2文档,但不确定要像以前一样设置样式解析。我已经尝试resolve.mainFiles指向曾经是resolve.root的内容,但这会导致构建错误。我也尝试output.devtoolModuleFilenameTemplatewebpack:///[resource-path]?[loaders],但绝对路径仍然存在。

' webpack:///'有什么意义?文件前缀与绝对文件路径?我应该转换为相对路径吗?我该怎么做?

2 个答案:

答案 0 :(得分:0)

我认为这是关于source-maps个文件的? 所以,当我调试JS时,文件加载为webpack:///,但之后我使用Cmd+o通过source-map打开文件,我能够打开文件。

答案 1 :(得分:0)

我找了一会儿,把它交给了一位同事后来发现css-loader现在正在使用abs路径:https://github.com/webpack-contrib/css-loader/releases/tag/v0.26.4

我发表了评论:https://github.com/webpack-contrib/css-loader/pull/430#issuecomment-326002386