tomachristian / css-entry-webpack-plugin

A Webpack plugin that simplifies creation of CSS-only bundles.
MIT License
39 stars 8 forks source link

Force extraction of entry if specified explicitly #16

Open tomachristian opened 7 years ago

tomachristian commented 7 years ago

If an entry is specified to be included explicitly using "entries" option, ignore the fact that non-CSS resources are specified in the entry.

NullVoxPopuli commented 7 years ago

could this be what's causing this error:

ERROR in ./css/application.scss
Module build failed: TypeError: text.forEach is not a function
    at Object.<anonymous> (/src/app/node_modules/extract-text-webpack-plugin/loader.js:115:10)
ERROR in /src/app/node_modules/extract-text-webpack-plugin/loader.js?{"id":2,"omit":0,"remove":true}!/src/app/node_modules/extract-text-webpack-plugin/loader.js??ref--2-0!/src/app/node_modules/style-loader/index.js!/src/app/node_modules/css-loader/index.js!/src/app/node_modules/sass-loader/lib/loader.js!/src/app/css/application.scss doesn't export content

ERROR in ./css/application.scss
Module build failed: TypeError: text.forEach is not a function
    at Object.<anonymous> (/src/app/node_modules/extract-text-webpack-plugin/loader.js:115:10)
tomachristian commented 7 years ago

@NullVoxPopuli Can you please attach your webpack configuration, or an excerpt of it? Also can you please provide your webpack, node and css-entry-webpack-plugin versions?

NullVoxPopuli commented 7 years ago

warning - walls of text:

I have stuff commented out right now for CssEntryPlugin. The build technically works as-is, but my global-styles are not seperated from my component styles (the idea here is that global styles would change less frequently).

I think it's not working, because my application.scss is a scss file. :-\ not sure entirely though.

config/webpack/main.config.js

const webpack = require('webpack');
const path = require('path');

const CssEntryPlugin = require("css-entry-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const autoprefixer = require('autoprefixer');

const nodeEnv = process.env.NODE_ENV || 'development';
const isProduction = nodeEnv === 'production';

const sourcePath = process.cwd();
const globalStylesPath = path.join(sourcePath, 'css');
const jsSourcePath = path.join(sourcePath, 'js');
const buildPath = path.join(sourcePath, 'dist');
const imgPath = path.join(sourcePath, 'images');

const babelSettings = {
  extends: path.join(sourcePath, '.babelrc')
};

// Common plugins
const plugins = [
  new ExtractTextPlugin({
    filename: '[name]-[hash].css',
    allChunks: true
  }),
  // new CssEntryPlugin({
  //   entries: ['styles'],
  //   output: {
  //     filename: '[name]-[hash].css'
  //   }
  // }),
  new webpack.optimize.CommonsChunkPlugin({
    name: 'vendor',
    minChunks: Infinity,
    filename: 'vendor-[hash].js'
  }),
  new webpack.DefinePlugin({
    'process.env': {
      NODE_ENV: JSON.stringify(nodeEnv),
    },
  }),
  new webpack.NamedModulesPlugin(),
  new HtmlWebpackPlugin({
    template: path.join(sourcePath, 'index.ejs'),
    inject: 'body',
    path: buildPath,
    filename: 'index.html',
    processEnv: JSON.stringify({
      CURRENT_ENV:     process.env.NODE_ENV || 'development',
      API_HOST:        process.env.API_HOST,
      AUTH0_CLIENT_ID: process.env.AUTH0_CLIENT_ID,
      AUTH0_DOMAIN:    process.env.AUTH0_DOMAIN,
      AUTH0_ENDPOINT:  process.env.AUTH0_ENDPOINT,
      APP_HOST:        process.env.APP_HOST,
    })
  }),
  new webpack.LoaderOptionsPlugin({
    options: {
      context: sourcePath,
      postcss: [
        autoprefixer({
          browsers: [
            'last 3 version',
            'ie >= 10',
          ],
        }),
      ],
    },
  }),
];

// Common rules
const rules = [
  {
    test: /\.jsx?$/,
    exclude: /node_modules/,
    loader: 'babel-loader?' + JSON.stringify(babelSettings),
  },
  {
    test: /\.(png|gif|jpg|svg)$/,
    include: imgPath,
    use: 'url-loader?limit=20480&name=assets/[name]-[hash].[ext]',
  },
  {
    test: /\.scss$/,
    exclude: /node_modules/,
    use: ExtractTextPlugin.extract({
      fallback: 'style-loader',
      use: [
        'css-loader',
        'sass-loader'
      ]
    })
  },
  {
    test: /\.css$/,
    use: ['css-loader']
  },
];

module.exports = {
  devtool: isProduction ? 'eval' : 'source-map',
  context: sourcePath,
  entry: {
    main: './js/main.js',
    // styles: './css/application.scss',
    vendor: [
      'babel-polyfill',
      'immutable',
      'whatwg-fetch',
      'react-dom',
      'react-redux',
      'react-router',
      'react',
      'redux-thunk',
      'redux',
      'd3',
      'd3-random',
      'auth0-lock'
    ],
  },
  output: {
    path: buildPath,
    // publicPath between the host and file url.
    // if assets live at the root, they should be at /
    publicPath: '/assets/',
    filename: '[name]-[hash].js',
  },
  module: {
    rules,
  },
  resolve: {
    extensions: ['.webpack-loader.js', '.web-loader.js', '.loader.js', '.js', '.jsx', '.css', '.scss'],
    modules: [
      path.resolve(sourcePath, 'node_modules'),
      jsSourcePath,
    ],
    alias: {
      js: jsSourcePath,
      css: globalStylesPath
    }
  },
  plugins
};

package.json dev-deps (no deps)

  "auth0-lock": "10.11.0",
    "autoprefixer": "^6.3.6",
    "babel-cli": "^6.24.0",
    "babel-core": "^6.24.0",
    "babel-eslint": "^6.1.0",
    "babel-jest": "^19.0.0",
    "babel-loader": "^6.4.1",
    "babel-plugin-transform-class-properties": "^6.23.0",
    "babel-plugin-transform-export-extensions": "^6.22.0",
    "babel-polyfill": "^6.23.0",
    "babel-preset-es2015": "^6.9.0",
    "babel-preset-es2016": "^6.22.0",
    "babel-preset-es2017": "^6.22.0",
    "babel-preset-react": "^6.23.0",
    "babel-preset-stage-0": "^6.22.0",
    "babel-preset-stage-2": "^6.22.0",
    "babel-preset-stage-3": "^6.22.0",
    "babel-watch": "^2.0.6",
    "bluebird": "^3.4.1",
    "bootstrap": "v4.0.0",
    "cleave.js": "^0.7.15",
    "copy-webpack-plugin": "^3.0.1",
    "css-entry-webpack-plugin": "^1.0.0-beta.4",
    "css-loader": "^0.28.0",
    "d3": "^4.4.4",
    "d3-random": "^1.0.0",
    "deep-assign": "^2.0.0",
    "deepmerge": "^1.3.0",
    "enzyme": "^2.6.0",
    "enzyme-matchers": "^3.0.0",
    "enzyme-redux": "^0.1.6",
    "eslint": "^3.16.1",
    "eslint-config-airbnb-base": "^11.1.0",
    "eslint-import-resolver-webpack": "^0.8.1",
    "eslint-loader": "^1.4.0",
    "eslint-plugin-babel": "^4.1.1",
    "eslint-plugin-import": "^2.2.0",
    "eslint-plugin-jest": "^19.0.1",
    "eslint-plugin-react": "^6.10.0",
    "extract-text-webpack-plugin": "^2.1.0",
    "file-loader": "^0.11.1",
    "html-webpack-plugin": "^2.28.0",
    "immutability-helper": "^2.1.2",
    "import-glob-loader": "^1.1.0",
    "imports-loader": "^0.7.1",
    "inject-loader": "^3.0.0",
    "jest": "^19.0.2",
    "jest-cli": "^19.0.2",
    "jestpack": "^0.2.0",
    "jquery-ui": "^1.10.5",
    "json-loader": "^0.5.4",
    "jsonwebtoken": "^7.1.3",
    "jwt-decode": "^2.1.0",
    "lodash": "^4.17.4",
    "moment": "^2.14.1",
    "moment-timezone": "^0.5.11",
    "node-sass": "^4.5.2",
    "on-build-webpack": "^0.1.0",
    "picolog": "^1.0.4",
    "postcss-cssnext": "^2.10.0",
    "postcss-import": "^9.1.0",
    "postcss-loader": "^1.3.3",
    "query-string": "^4.2.3",
    "react": "^15.4.2",
    "react-addons-test-utils": "^15.4.1",
    "react-binding": "^0.7.5",
    "react-body-classname": "^1.1.0",
    "react-bootstrap": "^0.30.8",
    "react-bootstrap-date-picker": "^5.0.1",
    "react-dom": "^15.4.1",
    "react-faux-dom": "^2.7.1",
    "react-file-input": "^0.2.5",
    "react-fontawesome": "^1.5.0",
    "react-hot-loader": "^1.3.1",
    "react-keydown": "^1.6.1",
    "react-password-strength": "^1.0.3",
    "react-range": "^0.0.7",
    "react-redux": "^4.4.5",
    "react-router": "^2.4.1",
    "react-router-redux": "^4.0.5",
    "react-select": "^1.0.0-rc.2",
    "redux": "^3.5.2",
    "redux-form": "^6.0.0",
    "redux-logger": "^2.6.4",
    "redux-mock-store": "^1.2.2",
    "redux-persist": "^3.2.2",
    "redux-promise": "^0.5.3",
    "redux-thunk": "^2.1.0",
    "resolve-url-loader": "^2.0.2",
    "sass-loader": "^6.0.3",
    "source-map-support": "^0.4.14",
    "style-loader": "^0.16.1",
    "tether": "^1.4.0",
    "uglify-js": "^2.8.21",
    "uglifyjs-webpack-plugin": "^0.4.1",
    "url-loader": "^0.5.8",
    "webpack": "^2.3.3",
    "webpack-config-helper": "^2.0.16",
    "webpack-dev-middleware": "^1.10.1",
    "webpack-dev-server": "^2.4.2",
    "webpack-hot-middleware": "^2.18.0",
    "whatwg-fetch": "^2.0.1"

Dockerfile

# This is a dev Dockerfile, since the frontend code needs to be built.
# There isn't a reason to have any of this be production-ready, except for
# dependency management.
FROM node:7

# Make sure yarn is installed, and that we have a directory to put the code.
RUN \
  curl -o- -L https://yarnpkg.com/install.sh | bash && \
  echo $(yarn --version) && \
  mkdir -p /src/app

WORKDIR /src/app
ADD package.json /src/app
ADD yarn.lock /src/app

RUN $HOME/.yarn/bin/yarn install

CMD ["npm", "run", "dev"]

docker-compose.yml

version: "2"
services:
  # https://github.com/yarnpkg/yarn/issues/749#issuecomment-253413954
  yarn-cache:
    image: busybox
    volumes:
      - /root/.yarn-cache
  web:
    build:
      context: .
      dockerfile: Dockerfile
    command: bash -c "npm run dev"
    volumes_from:
      - yarn-cache
    volumes:
      - ./config:/src/app/config
      - ./css:/src/app/css
      - ./images:/src/app/images
      - ./js:/src/app/js
      - ./test:/src/app/test
      - ./dist:/src/app/dist

      - ./package.json:/src/app/package.json

      - ./.eslintignore:/src/app/.eslintignore
      - ./.eslintrc.js:/src/app/.eslintrc.js
      - ./.babelrc:/src/app/.babelrc
      - ./.bootstraprc:/src/app/.bootstraprc

      - ./index.ejs:/src/app/index.ejs

    ports:
      - "4000:4000"
      - "8080:8080"
tomachristian commented 7 years ago

Thank you @NullVoxPopuli! I think this issue is because you use ExtractTextPlugin on all .scss files and CssEntryPlugin can't extract them properly (as they were already extracted). Unfortunately I can't test it out right now, but it seems that this is the problem.

As a workaround (until I can fix it) I propose you add an explicit rule for the files inside your "styles" bundle: Add { test: /application\.scss$/, use: [ 'css-loader', 'sass-loader' ] } BEFORE your existing rule for .scss files.