Giter VIP home page Giter VIP logo

preprocessor-loader's People

Contributors

afterwind-io avatar dependabot[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

preprocessor-loader's Issues

esbuild-loader compatibility

Does this loader compatible with esbuild-loader? I tried to make it worked, but my statements are not evaluated at compile time.

稍微负责的页面,你的testCase就通不过了,Full Test,javascript改为如下代码,就报错

'use strict';

import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
MapView,
TouchableHighlight,
TouchableOpacity,
ScrollView, ListView
} from 'react-native';

// import test from 'test';
// console.log('test', test);

let a = 1; // ...this line may be omitted.
// #!debug
a=2;
console.log("-----------a=",a);

const localAssets = {
// iconArrow: require('navigator/asset/icon_arrow.png'),
// iconArrow: require('../asset/icon_arrow.png'),
};
// let lazyModule =lazyRequire('./Page2.js');
// lazyModule.onModuleLoaded(function (module) {
// console.log('3@@@@@@@@@@@@@@@@@@@',module);
// });
//
// setTimeout(function(){
// let module = lazyModule.load();
// console.log('4@@@@@@@@@@@@@@@@@@@',module);
//
// }, 3000);

let ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => { return (r1.titleExtend != r2.titleExtend || r1.bizType != r2.bizType || r1.isFavoriteExtend !== r2.isFavoriteExtend) },
sectionHeaderHasChanged: (s1, s2) => { return s1 !== s2 },
getSectionHeaderData: (dataBlob, sectionID) => {
return DataManage.getSectionHeaderName(sectionID);
}
});

export default class Page1 extends Page {
constructor(props) {
super(props);
this.state = {
dataSource: ds.cloneWithRows(['John', 'Joel', 'James', 'Jimmy', 'Jackson', 'Jillian', 'Julie', 'Devin', "9", "10", "11 "]),
// dataSource: ds.cloneWithRowsAndSections(['John', 'Joel', 'James', 'Jimmy', 'Jackson', 'Jillian', 'Julie', 'Devin']),
loadState: 'normal', // 加载状态 normal-默认、loading-加载中、failed-加载失败、done-加载完成
};

	// fetch("https://sec-m.ctrip.com/restapi/soa2/10245/json/GetMonitoring?_rm=0.8329076717428225")
	// <LoadingFailedView />
}
render() {

	console.log('page1:render');

	return (
		<ViewPort>
			<View style={styles.container}>
				{undefined}
				
				<ListView
					style={{ flex: 1 }}
					dataSource={this.state.dataSource}
					renderRow={this.renderRow.bind(this)}

					onEndReached={this.onLoadMore.bind(this)}
					onEndReachedThreshold={300}
					renderFooter={this.renderFooter.bind(this)}
					pageSize={10}
				/>
				<Button
					onPress={() => {
						var img="";
						img = require('navigator/asset/icon_arrow.png');
						this.push('page2', { img });
					}}
					style={styles.button}>
					Back to Page2
					</Button>
				<Button onPress={() => this._getLocation()} style={styles.button}>
					点击定位
					</Button>
				<div {...this.props}>{undefined}{[undefined, <View>444</View>, undefined]}  333</div>
			</View>
		</ViewPort>
	);
}
_getLocation() {
	Location.locate({
		locateLevel: 0,
		timeout: 10000,
		isForceLocate: true // 是否强制定位
		//
	}).then(
		(data) => {
			console.log("-----success located:", data);
		}
		).catch(
		(err) => {
			console.log("--------locate failed:", err);
		}
		);
}

renderRow(rowData, sectionID, rowID) {

	if (!window.t1) {
		window.t1 = rowData;
	}
	return (
		<Text>Row data:{rowData}</Text>
	)
}
onLoadMore() {
	console.log('onLoadMore');
}
renderFooter() {
	console.log('renderFooter');
	return (<div>renderFooter</div>);
}
renderSeparator() {
	// renderSeparator={this.renderSeparator.bind(this)}
	// renderSectionHeader={this.renderSectionHeader.bind(this)}

	console.log('renderSeparator');
	return (<div>renderSeparator</div>);
}
renderSectionHeader() {
	console.log('renderSectionHeader');
	return (<div>renderSectionHeader</div>);
}

componentWillUnmount() {
	// tp('Page1 componentWillUnmount')
	// super.componentWillUnmount&&super.componentWillUnmount()
	// this.unmounted = true;
}

}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
button: {
"backgroundColor": "red"
},
fillStyle: {
backgroundColor: 'red'
},
backgroundStyle: {
backgroundColor: 'orange',
borderRadius: 1
},
ProgressBar1: {
"marginTop": 20,
"width": 200
}
});

The if directive implementation may cause wrong result

Currently the if directive is implemented by the following function:

export function ifComparator(params: IParamsMap, rawCondition: string): boolean {
    const keys = Object.keys(params);
    const values = keys.reduce((v, key) => v.concat(params[key]), []);
    const comparator = new Function(...keys, `return ${rawCondition};`);
    return comparator(...values);
}

v.concat may cause wrong result if the value type is Array. Just a little snippet:

const testObj = { a: 1, b: [0, 2, 3] };
const keys = Object.keys(testObj);
const values = keys.reduce((v, key) => v.concat(testObj[key]), []);

keys is ["a", "b"]
values is [1, 0, 2, 3]
(new Function(...keys, 'return b;'))(...values) will return 0, and this is an unexpected result.

A more robust way is to use push instead of concat.

v1.2.1 - comments processed incorrectly

After updated to the version v1.2.1 I got compilations error,
This happens when option verbose is set to the ``true.

Part of the original code:

    useTopWindow: false,
    /**
     * @property {Boolean} hashbang If set to `true`, when a hash is set, the hash will be prefixed
     * with an exclamation making it a hash bang instead of just a hash.
     *
     *     Ext.util.History.add('foo'); // will result in #foo
     *
     *     Ext.util.History.hashbang = true;
     *     Ext.util.History.add('bar'); // will result in #!bar
     */
    /**
     * @property {String} currentToken The current token.
     * @private
     */
    /**
     * @event ready
     * Fires when the Ext.util.History singleton has been initialized and is ready for use.
     * @param {Ext.util.History} history The Ext.util.History singleton.
     */
    /**
     * @event change
     * Fires when navigation back or forwards within the local page's history occurs.
     * @param {String} token An identifier associated with the page state at that point
     * in its history.
     */
    hashRe: /^(#?!?)/,

Error:

  ERROR in ../../../softvisio-node/ext/resources/ext-7.6.0/ext.js
  Module build failed (from ./node_modules/babel-loader/lib/index.js):
  SyntaxError: d:\projects\softvisio-node\ext\resources\ext-7.6.0\ext.js: Unexpected token (66015:6)

    66013 | /* * @property {String} currentToken The current token.*/
    66014 | /* * @private*/
  > 66015 | /* */*/
          |       ^
    66016 |     /**
    66017 |      * @event ready
    66018 |      * Fires when the Ext.util.History singleton has been initialized and is ready for use.
      at in

sass import 后条件编译无效

/* common.scss */
.test {
  // #!if NODE_ENV === 'production'
  color: red;
  // #!elseif NODE_ENV === 'development'
  color: blue;
  // #!endif
}
/* index.scss */
@import './common.scss'

当前 NODE_ENV'development'index.scss 最终编译后的是 color: red

Functions in params are not defined for the first time with thread-loader

When using a function in params, it is not defined for the first time that file is processed, however, on subsequent run (such as the second time using webpack watch), it is defined correctly.
We use the 'thread-loader', and removing that does seem to make this work fine.
However, with it enabled, the first time the file is processed, it produces and error.
I can tell it works on subsequent processing with "watch" because putting a console.log in the function prints to console.

The error is:

includeID is not defined

    at eval (eval at ifComparator (node_modules\webpack-preprocessor-loader\dist\filter.js:134:24), <anonymous>:3:1)

As far as I can tell, this is only the case for functions, and normal values are perfectly fine.

So, for example, we have this:

const Config = {
  units: ["Foo", "Baz"]
}
...
{
  loader: 'webpack-preprocessor-loader',
  options: {
    params: {
      includeID: function(id: string) {
        return Config.units.includes(id);
      }
  }
}

And then the file looks like this:

// #!if includeID("Foo")
import {} from 'units/Foo';
// #!endif

// #!if includeID("Bar")
import {} from 'units/Bar';
// #!endif

// #!if includeID("Baz")
import {} from 'units/Baz';
// #!endif

Some other things which might affect it:
The webpack config is done in TS not JS.
We use 'thread-loader', and removing that works.

自定义前缀

现在的写法是

// #!debug
console.log('1234');

直观感受是"(!)debug"

换成下面的是不是会好点

// !#debug
console.log('1234');

或者这个语法可以自定义

No errors when missing closing endifs

I guess this is more of a feature request than a bug per se, but when you have an #!if that usually requires an #!endif, but it's missing, no error is produced.

Is it possible to add an option, that if at the end of the file it is expecting an #!endif, and there isn't one, it can throw / log an error?

For example, say this is a file:

function MyFunc() {
  let x = "foo";
  #!if debug
  x  = "bar"
}

Because there is no closing #!endif, it means the rest of the file will be removed on non-debug builds.
Can an option be added where this will still have the same behaviour as now, but also logs this out as an error / warning if this missing #!endif is detected?

Nested if statements don't resolve correctly.

Nesting #!if statements in other #!if statements doesn't resolve how you would expect it to.

Having a param such as debug set to true, and then doing the following:

// #!if debug
    // #!if !debug
        // #!if debug
            console.log("hello")
        // #!endif
    // #!else
        console.log("world")
    // #!endif
// #!endif

You would expect it to output console.log("world"), however, console.log("hello") is produced.
Changing the first line to // #!if !debug doesn't change the output either, even though you would then expect neither line to exist.

Also, having something like this:

// #!if !debug
    // #!if debug && !debug
        console.log("hello")
    // #!endif
    console.log("world")
// #!endif

debug is true, so the expected output would be for the whole block to excluded. However, both #!if statements terminate at the first #!endif, and so regardless of the value of debug, console.log("world") is always outputted.

Tested on [email protected] & [email protected]

Verbose mode breaks in html files with css comments

Using verbose mode in HTML files has unexpected problems, when using comments in a <style> block.
If you have a css comment such as /* comment */, verbose mode switches to use that style of comment for the remainder of the "block" of commented out code.

For example:
TEST = false

<!-- #!if TEST -->
<style>
  #div1 {
    display: flex;
    flex-direction: column;
    /* 1px because of reasons */
    margin-left: 1px;
  }
</style>
<div id="div1">
  hello world
</div>
<!-- #!endif -->

the output becomes:

<!-- #!if TEST -->
<!-- <style> -->
<!-- #div1 { -->
<!-- display: flex; -->
<!-- flex-direction: column; -->
/* 1px because of reasons */
/* margin-left: 1px; */
/* } */
/* </style> */
/* <div id="div1"> */
/* hello world */
/* </div> */
<!-- #!endif -->

Which aren't html comments, and as such, the "div1" div is still rendered, although without the styling.

Putting a comment like:

</style>
<!-- fix comments -->
<div id="div1">

does sort of fix it, but it's not a great solution

Is there a feature that we can disable verbose mode for a block / for the singular file / for html files only?

vue-loader@next not working

Causes the condition compilation of html to fail

demo.vue:

<!-- #!if IS_PC -->
  <p>PC</p>
<!-- #!elseif IS_M -->
  <p>M</p>
<!-- #!endif -->

result:

<p>PC</p>
<p>M</p>

My npm config:

  • "webpack-preprocessor-loader": "^1.1.4",
  • "vue-loader": "^16.8.1",

Doesn't work with cache in webpack 5

When cache is enabled with webpack 5, modifying the preprocessor options will not trigger a cache bust and thus will use the cached version of the last compiled file as if the options were not changed

How can I use this with oneOf?

CRA gives you a webpack config that uses oneOf: for the loaders, how do I use this preprocessor with that???

Wondering if I should deal with it like the eslint pre-processor....

rules: [
        // Disable require.ensure as it's not a standard language feature.
        { parser: { requireEnsure: false, }, },

        // First, run the linter.
        // It's important to do this before Babel processes the JS.
        {
          test: /\.(js|mjs|jsx|ts|tsx)$/,
          enforce: 'pre',
          use: [
            {
              options: {
                cache: true,
                formatter: require.resolve('react-dev-utils/eslintFormatter'),
                eslintPath: require.resolve('eslint'),
                resolvePluginsRelativeTo: __dirname,

              },
              loader: require.resolve('eslint-loader'),
            },
          ],
          include: paths.appSrc,
        },
        {
          // "oneOf" will traverse all following loaders until one will
          // match the requirements. When no loader matches it will fall
          // back to the "file" loader at the end of the loader list.
          oneOf: [
            // "url" loader works like "file" loader except that it embeds assets
            // smaller than specified limit in bytes as data URLs to avoid requests.
            // A missing `test` is equivalent to a match.
            {
              test: [
                /\.bmp$/,
                /\.gif$/,
                /\.jpe?g$/,
                /\.png$/
                ,
              ],
              loader: require.resolve('url-loader'),
              options: {
                limit: imageInlineSizeLimit,
                name: 'static/media/[name].[hash:8].[ext]',
              },
            },
            // Process application JS with Babel.
            // The preset includes JSX, Flow, TypeScript, and some ESnext features.
            {
              test: /\.(js|mjs|jsx|ts|tsx)$/,
              include: paths.appSrc,
              loader: require.resolve('babel-loader'),
              options: {
                customize: require.resolve(
                  'babel-preset-react-app/webpack-overrides'
                ),
                presets: [ 'react-app', ],
                plugins: [
                  [
                    require.resolve('babel-plugin-named-asset-import'),
                    {
                      loaderMap: {
                        svg: {
                          ReactComponent:
                            '@svgr/webpack?-svgo,+titleProp,+ref![path]',
                        },
                      },
                    },
                  ],
                ],
                // This is a feature of `babel-loader` for webpack (not Babel itself).
                // It enables caching results in ./node_modules/.cache/babel-loader/
                // directory for faster rebuilds.
                cacheDirectory: true,
                // See #6846 for context on why cacheCompression is disabled
                cacheCompression: false,
                compact: isEnvProduction,
              },
            },
            // Process any JS outside of the app with Babel.
            // Unlike the application JS, we only compile the standard ES features.
            {
              test: /\.(js|mjs)$/,
              exclude: /@babel(?:\/|\\{1,2})runtime/,
              loader: require.resolve('babel-loader'),
              options: {
                babelrc: false,
                configFile: false,
                compact: false,
                presets: [
                  [
                    require.resolve('babel-preset-react-app/dependencies'),
                    { helpers: true, },
                  ],
                ],
                cacheDirectory: true,
                // See #6846 for context on why cacheCompression is disabled
                cacheCompression: false,

                // Babel sourcemaps are needed for debugging into node_modules
                // code.  Without the options below, debuggers like VSCode
                // show incorrect code and set breakpoints on the wrong lines.
                sourceMaps: shouldUseSourceMap,
                inputSourceMap: shouldUseSourceMap,
              },
            },
            // "postcss" loader applies autoprefixer to our CSS.
            // "css" loader resolves paths in CSS and adds assets as dependencies.
            // "style" loader turns CSS into JS modules that inject <style> tags.
            // In production, we use MiniCSSExtractPlugin to extract that CSS
            // to a file, but in development "style" loader enables hot editing
            // of CSS.
            // By default we support CSS Modules with the extension .module.css
            {
              test: cssRegex,
              exclude: cssModuleRegex,
              use: getStyleLoaders({
                importLoaders: 1,
                sourceMap: isEnvProduction && shouldUseSourceMap,
              }),
              // Don't consider CSS imports dead code even if the
              // containing package claims to have no side effects.
              // Remove this when webpack adds a warning or an error for this.
              // See https://github.com/webpack/webpack/issues/6571
              sideEffects: true,
            },
            // Adds support for CSS Modules (https://github.com/css-modules/css-modules)
            // using the extension .module.css
            {
              test: cssModuleRegex,
              use: getStyleLoaders({
                importLoaders: 1,
                sourceMap: isEnvProduction && shouldUseSourceMap,
                modules: {
                  getLocalIdent: getCSSModuleLocalIdent,
                },
              }),
            },
            // Opt-in support for SASS (using .scss or .sass extensions).
            // By default we support SASS Modules with the
            // extensions .module.scss or .module.sass
            {
              test: sassRegex,
              exclude: sassModuleRegex,
              use: getStyleLoaders(
                {
                  importLoaders: 2,
                  sourceMap: isEnvProduction && shouldUseSourceMap,
                },
                'sass-loader'
              ),
              // Don't consider CSS imports dead code even if the
              // containing package claims to have no side effects.
              // Remove this when webpack adds a warning or an error for this.
              // See https://github.com/webpack/webpack/issues/6571
              sideEffects: true,
            },
            // Adds support for CSS Modules, but using SASS
            // using the extension .module.scss or .module.sass
            {
              test: sassModuleRegex,
              use: getStyleLoaders(
                {
                  importLoaders: 2,
                  sourceMap: isEnvProduction && shouldUseSourceMap,
                  modules: {
                    getLocalIdent: getCSSModuleLocalIdent,
                  },
                },
                'sass-loader'
              ),
            },
            // "file" loader makes sure those assets get served by WebpackDevServer.
            // When you `import` an asset, you get its (virtual) filename.
            // In production, they would get copied to the `build` folder.
            // This loader doesn't use a "test" so it will catch all modules
            // that fall through the other loaders.
            {
              loader: require.resolve('file-loader'),
              // Exclude `js` files to keep "css" loader working as it injects
              // its runtime that would otherwise be processed through "file" loader.
              // Also exclude `html` and `json` extensions so they get processed
              // by webpacks internal loaders.
              exclude: [
                /\.(js|mjs|jsx|ts|tsx)$/,
                /\.html$/,
                /\.json$/
                ,
              ],
              options: {
                name: 'static/media/[name].[hash:8].[ext]',
              },
            },
            // ** STOP ** Are you adding a new loader?
            // Make sure to add the new loader(s) before the "file" loader.
          ],
        },
      ],

Test libraries

Hello, does it work with test libraries ?

How to use it with jest ?

Failed when having export default from imported

Hi, @afterwind-io

I've found this loader does not work in the case when having export default from another imported default module.

For example,

// File ./components/a.js
const someFunc = () => { // do something };
export default someFunc;
// File ./components/index.js
import someFunc from "./a"
export default someFunc;
// File app.js
import someFunc from "./components"

someFunc();

It will throw errors when compling

WARNING in app.js
"export 'default' (imported as 'someFunc') was not found in 'app.js'

It would be glad to see any response from you.
Thanks.

Support for Angular Project Generated by Angular CLI

This issue is the continuous discussion of #6.

TL;DR Currently there is no easy workaround to gracefully apply the preprocessor and keep an accurate source map at the same time.

The real problem here is, during the compilation, Angular just loads all the files from the file system. All content generated by last loader (webpack-preprocessor-loader in this case) is neglected, which means:

angular.json, with @angular-builders/custom-webpack

"architect": {
  "build": {
    "builder": "@angular-builders/custom-webpack:browser",
    "options": {
      "customWebpackConfig": {
        "path": "webpack.config.js",
        "mergeStrategies": {
          "module.rules": "append"
        }

...with webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: [
          {
            loader: "webpack-preprocessor-loader",
            options: {
              debug: false,
            }
          },
        // ...

... actually does not work at all.

If we modify the mergeStrategies to prepend, another problem rises. The preprocessor now takes js file, compiled by Angular, as its source. Currently the preprocessor will not pass the source map to the next loader (and it should not, because the preprocessor is meant to deal with the original code directly, thus no source map from upstream). As a result, the source map generated by Angular (js -> ts) is lost. So the final source map we do see in the inspector is a mapping between the bundled file and corresponding compiled code file, which is not intended. But the mapping is accurate though.

Then what about just passing the source map downward? Well, here is the reference from the earlier discussion:

Certain lines of code would likely be cut during preprocessing, and it can leads to potential problems. If source map generated from upstream does exist, it does not "know" the fact that some code will be trimmed afterwards, because the source map itself is based on the processed code from last step. In conclusion, the mapping would be broken and it will create offset after the cuts.

In conclusion, to handle the problem properly, the preprocessor need to generate its own source map, and maybe based on the potential source map from upstream, which is far beyond the intended usage of this loader.

If anyone who is interested and has better idea/workaround, please feel free to leave your solution below. Thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.